mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
More test abstractions for multiple databases (#950)
* Remove unnecessary import of rethinkdb in a test * Move test_run_query_util as a rethinkdb-specific test * Move rethinkdb-specific command tests to own file * Add __init__.py to new test folders * Move command tests to their own test module * Move fixtures out of command tests into separate conftest for commands * Fix some small flake8 issues with rethinkdb's test_run_query_util * Add pytest ignore hook to filter out test dirs that are not for the requested backend * Move backend-specific tests in tests/db/ to tests/backend/
This commit is contained in:
parent
c81e7a7479
commit
b4063dd9ad
0
tests/backend/rethinkdb/__init__.py
Normal file
0
tests/backend/rethinkdb/__init__.py
Normal file
@ -25,7 +25,6 @@ def test_raise_exception_when_max_tries():
|
||||
|
||||
def test_reconnect_when_connection_lost():
|
||||
import time
|
||||
import rethinkdb as r
|
||||
|
||||
def raise_exception(*args, **kwargs):
|
||||
raise r.ReqlDriverError('mock')
|
||||
@ -65,18 +64,18 @@ def test_changefeed_reconnects_when_connection_lost(monkeypatch):
|
||||
if self.tries == 1:
|
||||
raise r.ReqlDriverError('mock')
|
||||
elif self.tries == 2:
|
||||
return { 'new_val': { 'fact': 'A group of cats is called a clowder.' },
|
||||
'old_val': None }
|
||||
return {'new_val': {'fact': 'A group of cats is called a clowder.'},
|
||||
'old_val': None}
|
||||
if self.tries == 3:
|
||||
raise r.ReqlDriverError('mock')
|
||||
elif self.tries == 4:
|
||||
return { 'new_val': {'fact': 'Cats sleep 70% of their lives.' },
|
||||
'old_val': None }
|
||||
return {'new_val': {'fact': 'Cats sleep 70% of their lives.'},
|
||||
'old_val': None}
|
||||
else:
|
||||
time.sleep(10)
|
||||
|
||||
changefeed = RethinkDBChangeFeed('cat_facts', ChangeFeed.INSERT,
|
||||
connection=MockConnection())
|
||||
connection=MockConnection())
|
||||
changefeed.outqueue = mp.Queue()
|
||||
t_changefeed = Thread(target=changefeed.run_forever, daemon=True)
|
||||
|
0
tests/commands/__init__.py
Normal file
0
tests/commands/__init__.py
Normal file
41
tests/commands/conftest.py
Normal file
41
tests/commands/conftest.py
Normal file
@ -0,0 +1,41 @@
|
||||
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_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.commands import bigchain
|
||||
monkeypatch.setattr(bigchain, '_run_init', lambda: None)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_processes_start(monkeypatch):
|
||||
from bigchaindb import processes
|
||||
monkeypatch.setattr(processes, 'start', lambda *args: None)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_generate_key_pair(monkeypatch):
|
||||
monkeypatch.setattr('bigchaindb.common.crypto.generate_key_pair', lambda: ('privkey', 'pubkey'))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_bigchaindb_backup_config(monkeypatch):
|
||||
config = {
|
||||
'keypair': {},
|
||||
'database': {'host': 'host', 'port': 12345, 'name': 'adbname'},
|
||||
'statsd': {'host': 'host', 'port': 12345, 'rate': 0.1},
|
||||
'backlog_reassign_delay': 5
|
||||
}
|
||||
monkeypatch.setattr('bigchaindb._config', config)
|
0
tests/commands/rethinkdb/__init__.py
Normal file
0
tests/commands/rethinkdb/__init__.py
Normal file
123
tests/commands/rethinkdb/test_commands.py
Normal file
123
tests/commands/rethinkdb/test_commands.py
Normal file
@ -0,0 +1,123 @@
|
||||
import pytest
|
||||
import rethinkdb
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
from argparse import Namespace
|
||||
|
||||
|
||||
@patch('bigchaindb.commands.utils.start_rethinkdb', return_value=Mock())
|
||||
def test_bigchain_run_start_with_rethinkdb(mock_start_rethinkdb,
|
||||
mock_run_configure,
|
||||
mock_processes_start,
|
||||
mock_db_init_with_existing_db):
|
||||
from bigchaindb.commands.bigchain import run_start
|
||||
args = Namespace(start_rethinkdb=True, allow_temp_keypair=False, config=None, yes=True)
|
||||
run_start(args)
|
||||
|
||||
mock_start_rethinkdb.assert_called_with()
|
||||
|
||||
|
||||
@patch('subprocess.Popen')
|
||||
def test_start_rethinkdb_returns_a_process_when_successful(mock_popen):
|
||||
from bigchaindb.commands import utils
|
||||
mock_popen.return_value = Mock(stdout=[
|
||||
'Listening for client driver 1234',
|
||||
'Server ready'])
|
||||
assert utils.start_rethinkdb() is mock_popen.return_value
|
||||
|
||||
|
||||
@patch('subprocess.Popen')
|
||||
def test_start_rethinkdb_exits_when_cannot_start(mock_popen):
|
||||
from bigchaindb.common import exceptions
|
||||
from bigchaindb.commands import utils
|
||||
mock_popen.return_value = Mock(stdout=['Nopety nope'])
|
||||
with pytest.raises(exceptions.StartupError):
|
||||
utils.start_rethinkdb()
|
||||
|
||||
|
||||
@patch('rethinkdb.ast.Table.reconfigure')
|
||||
def test_set_shards(mock_reconfigure, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_shards
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return one replica
|
||||
def mockreturn_one_replica(self, conn):
|
||||
return {'shards': [{'replicas': [1]}]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_one_replica)
|
||||
args = Namespace(num_shards=3)
|
||||
run_set_shards(args)
|
||||
mock_reconfigure.assert_called_with(replicas=1, shards=3)
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return three replica
|
||||
def mockreturn_three_replicas(self, conn):
|
||||
return {'shards': [{'replicas': [1, 2, 3]}]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_three_replicas)
|
||||
run_set_shards(args)
|
||||
mock_reconfigure.assert_called_with(replicas=3, shards=3)
|
||||
|
||||
|
||||
@patch('logging.Logger.warn')
|
||||
def test_set_shards_raises_exception(mock_log, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_shards
|
||||
|
||||
# test that we are correctly catching the exception
|
||||
def mock_raise(*args, **kwargs):
|
||||
raise rethinkdb.ReqlOpFailedError('')
|
||||
|
||||
def mockreturn_one_replica(self, conn):
|
||||
return {'shards': [{'replicas': [1]}]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_one_replica)
|
||||
monkeypatch.setattr(rethinkdb.ast.Table, 'reconfigure', mock_raise)
|
||||
|
||||
args = Namespace(num_shards=3)
|
||||
run_set_shards(args)
|
||||
|
||||
assert mock_log.called
|
||||
|
||||
|
||||
@patch('rethinkdb.ast.Table.reconfigure')
|
||||
def test_set_replicas(mock_reconfigure, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_replicas
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return two shards
|
||||
def mockreturn_two_shards(self, conn):
|
||||
return {'shards': [1, 2]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_two_shards)
|
||||
args = Namespace(num_replicas=2)
|
||||
run_set_replicas(args)
|
||||
mock_reconfigure.assert_called_with(replicas=2, shards=2)
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return three shards
|
||||
def mockreturn_three_shards(self, conn):
|
||||
return {'shards': [1, 2, 3]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_three_shards)
|
||||
run_set_replicas(args)
|
||||
mock_reconfigure.assert_called_with(replicas=2, shards=3)
|
||||
|
||||
|
||||
@patch('logging.Logger.warn')
|
||||
def test_set_replicas_raises_exception(mock_log, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_replicas
|
||||
|
||||
# test that we are correctly catching the exception
|
||||
def mock_raise(*args, **kwargs):
|
||||
raise rethinkdb.ReqlOpFailedError('')
|
||||
|
||||
def mockreturn_two_shards(self, conn):
|
||||
return {'shards': [1, 2]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_two_shards)
|
||||
monkeypatch.setattr(rethinkdb.ast.Table, 'reconfigure', mock_raise)
|
||||
|
||||
args = Namespace(num_replicas=2)
|
||||
run_set_replicas(args)
|
||||
|
||||
assert mock_log.called
|
@ -4,47 +4,6 @@ from argparse import Namespace
|
||||
import copy
|
||||
|
||||
import pytest
|
||||
import rethinkdb
|
||||
|
||||
|
||||
@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_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.commands import bigchain
|
||||
monkeypatch.setattr(bigchain, '_run_init', lambda: None)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_processes_start(monkeypatch):
|
||||
from bigchaindb import processes
|
||||
monkeypatch.setattr(processes, 'start', lambda *args: None)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_generate_key_pair(monkeypatch):
|
||||
monkeypatch.setattr('bigchaindb.common.crypto.generate_key_pair', lambda: ('privkey', 'pubkey'))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_bigchaindb_backup_config(monkeypatch):
|
||||
config = {
|
||||
'keypair': {},
|
||||
'database': {'host': 'host', 'port': 12345, 'name': 'adbname'},
|
||||
'statsd': {'host': 'host', 'port': 12345, 'rate': 0.1},
|
||||
'backlog_reassign_delay': 5
|
||||
}
|
||||
monkeypatch.setattr('bigchaindb._config', config)
|
||||
|
||||
|
||||
def test_make_sure_we_dont_remove_any_command():
|
||||
@ -114,18 +73,6 @@ def test_bigchain_run_start(mock_run_configure, mock_processes_start, mock_db_in
|
||||
run_start(args)
|
||||
|
||||
|
||||
@patch('bigchaindb.commands.utils.start_rethinkdb', return_value=Mock())
|
||||
def test_bigchain_run_start_with_rethinkdb(mock_start_rethinkdb,
|
||||
mock_run_configure,
|
||||
mock_processes_start,
|
||||
mock_db_init_with_existing_db):
|
||||
from bigchaindb.commands.bigchain import run_start
|
||||
args = Namespace(start_rethinkdb=True, allow_temp_keypair=False, config=None, yes=True)
|
||||
run_start(args)
|
||||
|
||||
mock_start_rethinkdb.assert_called_with()
|
||||
|
||||
|
||||
@pytest.mark.skipif(reason="BigchainDB doesn't support the automatic creation of a config file anymore")
|
||||
def test_bigchain_run_start_assume_yes_create_default_config(monkeypatch, mock_processes_start,
|
||||
mock_generate_key_pair, mock_db_init_with_existing_db):
|
||||
@ -280,24 +227,6 @@ def test_run_configure_when_config_does_exist(monkeypatch,
|
||||
assert value == {}
|
||||
|
||||
|
||||
@patch('subprocess.Popen')
|
||||
def test_start_rethinkdb_returns_a_process_when_successful(mock_popen):
|
||||
from bigchaindb.commands import utils
|
||||
mock_popen.return_value = Mock(stdout=[
|
||||
'Listening for client driver 1234',
|
||||
'Server ready'])
|
||||
assert utils.start_rethinkdb() is mock_popen.return_value
|
||||
|
||||
|
||||
@patch('subprocess.Popen')
|
||||
def test_start_rethinkdb_exits_when_cannot_start(mock_popen):
|
||||
from bigchaindb.common import exceptions
|
||||
from bigchaindb.commands import utils
|
||||
mock_popen.return_value = Mock(stdout=['Nopety nope'])
|
||||
with pytest.raises(exceptions.StartupError):
|
||||
utils.start_rethinkdb()
|
||||
|
||||
|
||||
@patch('bigchaindb.common.crypto.generate_key_pair',
|
||||
return_value=('private_key', 'public_key'))
|
||||
@pytest.mark.usefixtures('restore_config')
|
||||
@ -339,94 +268,6 @@ def test_allow_temp_keypair_doesnt_override_if_keypair_found(mock_gen_keypair,
|
||||
assert bigchaindb.config['keypair']['public'] == original_public_key
|
||||
|
||||
|
||||
@patch('rethinkdb.ast.Table.reconfigure')
|
||||
def test_set_shards(mock_reconfigure, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_shards
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return one replica
|
||||
def mockreturn_one_replica(self, conn):
|
||||
return {'shards': [{'replicas': [1]}]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_one_replica)
|
||||
args = Namespace(num_shards=3)
|
||||
run_set_shards(args)
|
||||
mock_reconfigure.assert_called_with(replicas=1, shards=3)
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return three replica
|
||||
def mockreturn_three_replicas(self, conn):
|
||||
return {'shards': [{'replicas': [1, 2, 3]}]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_three_replicas)
|
||||
run_set_shards(args)
|
||||
mock_reconfigure.assert_called_with(replicas=3, shards=3)
|
||||
|
||||
|
||||
@patch('logging.Logger.warn')
|
||||
def test_set_shards_raises_exception(mock_log, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_shards
|
||||
|
||||
# test that we are correctly catching the exception
|
||||
def mock_raise(*args, **kwargs):
|
||||
raise rethinkdb.ReqlOpFailedError('')
|
||||
|
||||
def mockreturn_one_replica(self, conn):
|
||||
return {'shards': [{'replicas': [1]}]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_one_replica)
|
||||
monkeypatch.setattr(rethinkdb.ast.Table, 'reconfigure', mock_raise)
|
||||
|
||||
args = Namespace(num_shards=3)
|
||||
run_set_shards(args)
|
||||
|
||||
assert mock_log.called
|
||||
|
||||
|
||||
@patch('rethinkdb.ast.Table.reconfigure')
|
||||
def test_set_replicas(mock_reconfigure, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_replicas
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return two shards
|
||||
def mockreturn_two_shards(self, conn):
|
||||
return {'shards': [1, 2]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_two_shards)
|
||||
args = Namespace(num_replicas=2)
|
||||
run_set_replicas(args)
|
||||
mock_reconfigure.assert_called_with(replicas=2, shards=2)
|
||||
|
||||
# this will mock the call to retrieve the database config
|
||||
# we will set it to return three shards
|
||||
def mockreturn_three_shards(self, conn):
|
||||
return {'shards': [1, 2, 3]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_three_shards)
|
||||
run_set_replicas(args)
|
||||
mock_reconfigure.assert_called_with(replicas=2, shards=3)
|
||||
|
||||
|
||||
@patch('logging.Logger.warn')
|
||||
def test_set_replicas_raises_exception(mock_log, monkeypatch, b):
|
||||
from bigchaindb.commands.bigchain import run_set_replicas
|
||||
|
||||
# test that we are correctly catching the exception
|
||||
def mock_raise(*args, **kwargs):
|
||||
raise rethinkdb.ReqlOpFailedError('')
|
||||
|
||||
def mockreturn_two_shards(self, conn):
|
||||
return {'shards': [1, 2]}
|
||||
|
||||
monkeypatch.setattr(rethinkdb.RqlQuery, 'run', mockreturn_two_shards)
|
||||
monkeypatch.setattr(rethinkdb.ast.Table, 'reconfigure', mock_raise)
|
||||
|
||||
args = Namespace(num_replicas=2)
|
||||
run_set_replicas(args)
|
||||
|
||||
assert mock_log.called
|
||||
|
||||
|
||||
@patch('argparse.ArgumentParser.parse_args')
|
||||
@patch('bigchaindb.commands.utils.base_parser')
|
||||
@patch('bigchaindb.commands.utils.start')
|
@ -44,6 +44,17 @@ def pytest_addoption(parser):
|
||||
)
|
||||
|
||||
|
||||
def pytest_ignore_collect(path, config):
|
||||
from bigchaindb.backend.connection import BACKENDS
|
||||
path = str(path)
|
||||
|
||||
if os.path.isdir(path):
|
||||
dirname = os.path.split(path)[1]
|
||||
if dirname in BACKENDS.keys() and dirname != config.getoption('--database-backend'):
|
||||
print('Ignoring unrequested backend test dir: ', path)
|
||||
return True
|
||||
|
||||
|
||||
# We need this function to avoid loading an existing
|
||||
# conf file located in the home of the user running
|
||||
# the tests. If it's too aggressive we can change it
|
||||
|
Loading…
x
Reference in New Issue
Block a user