Exemple #1
0
 def setUp(self):
     self.store = '/tmp/store.json'
     self.dest = '/tmp/dbs'
     self.config = gen_test_config()
     if not os.path.exists(self.dest):
         os.mkdir(self.dest)
     self.handler = DatabaseStore(self.config)
Exemple #2
0
    def setUp(self):
        self.store = '/tmp/store.json'
        self.dest = '/tmp/dbs'
        self.config = gen_test_config()
        if not os.path.exists(self.dest):
            os.mkdir(self.dest)

        self.databases = DatabaseStore(self.config)
        self.default_db_uid = self.databases.index['name_to_uid']['default']
        self._bootstrap_db(self.databases[self.default_db_uid].connector)
        self.handler = Handler(self.databases)
Exemple #3
0
class MajordomeTest(unittest2.TestCase):
    def setUp(self):
        zmq_context = zmq.Context()
        env = gen_test_env()

        self.database_store = env['global']['database_store']
        self.databases_storage_path = env['global']['databases_storage_path']

        if not os.path.exists(self.databases_storage_path):
            os.mkdir(self.databases_storage_path)

        self.db_handler = DatabaseStore(self.database_store,
                                           self.databases_storage_path)

        # Let's fake a backend for workers to talk to
        self.socket = zmq_context.socket(zmq.DEALER)
        self.socket.bind('inproc://backend')

        self.supervisor = Supervisor(zmq_context, self.db_handler)

    def tearDown(self):
        self.supervisor.stop_all()

        if hasattr(self, 'majordome'):
            self.majordome.cancel()

        os.remove(self.database_store)
        shutil.rmtree(self.databases_storage_path)

    def test_unmount_existing_mounted_database(self):
        default_db_uid = self.db_handler.index['name_to_uid']['default']
        db_to_watch = self.db_handler[default_db_uid]
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.MOUNTED)

        # Use 1/60 interval in order to set it as 1sec
        self.majordome = Majordome(self.supervisor,
                                   self.db_handler,
                                   1 / 60)
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.MOUNTED)

    def test_unmount_existing_unmounted_database(self):
        default_db_uid = self.db_handler.index['name_to_uid']['default']
        db_to_watch = self.db_handler[default_db_uid]

        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.MOUNTED)
        self.db_handler.umount('default')
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.UNMOUNTED)

        # Use 1/60 interval in order to set it as 1sec
        self.majordome = Majordome(self.supervisor,
                                   self.db_handler,
                                   1 / 60)
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.UNMOUNTED)
Exemple #4
0
class MajordomeTest(unittest2.TestCase):
    def setUp(self):
        zmq_context = zmq.Context()
        config = gen_test_config()

        self.database_store = config['database_store']
        self.databases_storage_path = config['databases_storage_path']

        if not os.path.exists(self.databases_storage_path):
            os.mkdir(self.databases_storage_path)

        self.db_handler = DatabaseStore(config)

        # Let's fake a backend for workers to talk to
        self.socket = zmq_context.socket(zmq.DEALER)
        self.socket.bind('inproc://backend')

        self.supervisor = Supervisor(zmq_context, self.db_handler)

    def tearDown(self):
        self.supervisor.stop_all()

        if hasattr(self, 'majordome'):
            self.majordome.cancel()

        os.remove(self.database_store)
        shutil.rmtree(self.databases_storage_path)

    def test_unmount_existing_mounted_database(self):
        default_db_uid = self.db_handler.index['name_to_uid']['default']
        db_to_watch = self.db_handler[default_db_uid]
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.MOUNTED)

        # Use 1/60 interval in order to set it as 1sec
        self.majordome = Majordome(self.supervisor, self.db_handler, 1 / 60)
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.MOUNTED)

    def test_unmount_existing_unmounted_database(self):
        default_db_uid = self.db_handler.index['name_to_uid']['default']
        db_to_watch = self.db_handler[default_db_uid]

        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.MOUNTED)
        self.db_handler.umount('default')
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.UNMOUNTED)

        # Use 1/60 interval in order to set it as 1sec
        self.majordome = Majordome(self.supervisor, self.db_handler, 1 / 60)
        self.assertEqual(db_to_watch.status, DatabaseStore.STATUSES.UNMOUNTED)
Exemple #5
0
 def setUp(self):
     self.store = '/tmp/store.json'
     self.dest = '/tmp/dbs'
     self.config = gen_test_config()
     if not os.path.exists(self.dest):
         os.mkdir(self.dest)
     self.handler = DatabaseStore(self.config)
Exemple #6
0
    def setUp(self):
        zmq_context = zmq.Context()
        config = gen_test_config()

        self.database_store = config['database_store']
        self.databases_storage_path = config['databases_storage_path']

        if not os.path.exists(self.databases_storage_path):
            os.mkdir(self.databases_storage_path)

        self.db_handler = DatabaseStore(config)

        # Let's fake a backend for workers to talk to
        self.socket = zmq_context.socket(zmq.DEALER)
        self.socket.bind('inproc://backend')

        self.supervisor = Supervisor(zmq_context, self.db_handler)
Exemple #7
0
    def setUp(self):
        self.store = '/tmp/store.json'
        self.dest = '/tmp/dbs'
        self.config = gen_test_config()
        if not os.path.exists(self.dest):
            os.mkdir(self.dest)

        self.databases = DatabaseStore(self.config)
        self.default_db_uid = self.databases.index['name_to_uid']['default']
        self._bootstrap_db(self.databases[self.default_db_uid].connector)
        self.handler = Handler(self.databases)
Exemple #8
0
    def setUp(self):
        zmq_context = zmq.Context()
        config = gen_test_config()

        self.database_store = config['database_store']
        self.databases_storage_path = config['databases_storage_path']

        if not os.path.exists(self.databases_storage_path):
            os.mkdir(self.databases_storage_path)

        self.db_handler = DatabaseStore(config)

        # Let's fake a backend for workers to talk to
        self.socket = zmq_context.socket(zmq.DEALER)
        self.socket.bind('inproc://backend')

        self.supervisor = Supervisor(zmq_context, self.db_handler)
Exemple #9
0
def runserver(config):
    setup_loggers(config)
    activity_logger = logging.getLogger("activity_logger")

    databases = DatabaseStore(config)
    backend = Backend(databases, config)
    frontend = Frontend(config)

    poller = zmq.Poller()
    poller.register(backend.socket, zmq.POLLIN)
    poller.register(frontend.socket, zmq.POLLIN)

    activity_logger.info('Elevator server started on %s' % frontend.host)

    while True:
        try:
            sockets = dict(poller.poll())
            if frontend.socket in sockets:
                if sockets[frontend.socket] == zmq.POLLIN:
                    msg = frontend.socket.recv_multipart(copy=False)
                    backend.socket.send_multipart(msg, copy=False)

            if backend.socket in sockets:
                if sockets[backend.socket] == zmq.POLLIN:
                    msg = backend.socket.recv_multipart(copy=False)
                    frontend.socket.send_multipart(msg, copy=False)
        except KeyboardInterrupt:
            activity_logger.info('Gracefully shuthing down workers')
            del backend
            activity_logger.info('Stopping frontend')
            del frontend
            activity_logger.info('Done')
            return
        except Exception as e:
            log_critical(e)
            del backend
            del frontend
            return
Exemple #10
0
class ApiTests(unittest2.TestCase):
    def _bootstrap_db(self, db):
        for val in xrange(9):
            db.put(str(val), str(val + 10))

    def setUp(self):
        self.store = '/tmp/store.json'
        self.dest = '/tmp/dbs'
        self.config = gen_test_config()
        if not os.path.exists(self.dest):
            os.mkdir(self.dest)

        self.databases = DatabaseStore(self.config)
        self.default_db_uid = self.databases.index['name_to_uid']['default']
        self._bootstrap_db(self.databases[self.default_db_uid].connector)
        self.handler = Handler(self.databases)

    def tearDown(self):
        self.databases.__del__()
        del self.handler
        os.remove(self.store)
        shutil.rmtree(self.dest)

    def request_message(self, command, args, db_uid=None):
        db_uid = db_uid or self.default_db_uid
        return Request(
            msgpack.packb({
                'uid': db_uid,
                'cmd': command,
                'args': args,
            }))

    def test_command_with_existing_command(self):
        message = self.request_message('GET', ['1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertNotEqual(plain_content['datas'], None)

    def test_command_with_non_existing_command(self):
        message = self.request_message('COTCOT', ['testarg'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], KEY_ERROR)

    def test_command_with_invalid_db_uid(self):
        message = self.request_message('PUT', ['1', '1'], db_uid='failinguid')
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], RUNTIME_ERROR)

    def test_get_of_existing_key(self):
        message = self.request_message('GET', ['1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], ('11', ))

    def test_get_of_non_existing_key(self):
        message = self.request_message('GET', ['abc123'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], KEY_ERROR)

    def test_mget_of_existing_keys(self):
        message = self.request_message('MGET', [['1', '2', '3']])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], ('11', '12', '13'))

    def test_mget_of_not_fully_existing_keys(self):
        message = self.request_message('MGET', [['1', '2', 'touptoupidou']])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], WARNING_STATUS)
        self.assertEqual(len(plain_content['datas']), 3)
        self.assertEqual(plain_content['datas'], ('11', '12', None))

    def test_put_of_valid_key(self):
        message = self.request_message('PUT', ['a', '1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_put_of_invalid_value(self):
        message = self.request_message('PUT', ['a', 1])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], TYPE_ERROR)

    def test_delete(self):
        message = self.request_message('DELETE', ['9'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_exists_of_existing_key(self):
        message = self.request_message('EXISTS', ['1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], True)

    def test_exists_of_non_existing_key_1(self):
        message = self.request_message('EXISTS', ['0'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], False)

    def test_exists_of_non_existing_key_2(self):
        message = self.request_message('EXISTS', ['non_existing'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], False)

    def test_range(self):
        message = self.request_message('RANGE', ['1', '2'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(plain_content['datas'][0], ('1', '11'))
        self.assertEqual(plain_content['datas'][1], ('2', '12'))

    def test_range_with_keys_only(self):
        message = self.request_message('RANGE', ['1', '2', True, False])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)

        self.assertEqual(len(plain_content['datas'][0]), 1)
        self.assertEqual(len(plain_content['datas'][1]), 1)

        self.assertEqual(plain_content['datas'][0], ('1'))
        self.assertEqual(plain_content['datas'][1], ('2'))

    def test_range_of_len_one(self):
        """Should still return a tuple of tuple"""
        message = self.request_message('RANGE', ['1', '1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(len(plain_content), 1)
        self.assertEqual(plain_content['datas'], (('1', '11'), ))

    def test_slice_with_limit(self):
        message = self.request_message('SLICE', ['1', 3])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(len(plain_content['datas']), 3)
        self.assertEqual(plain_content['datas'][0], ('1', '11'))
        self.assertEqual(plain_content['datas'][1], ('2', '12'))
        self.assertEqual(plain_content['datas'][2], ('3', '13'))

    def test_slice_with_limit_value_of_one(self):
        message = self.request_message('SLICE', ['1', 1])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(len(plain_content), 1)
        self.assertEqual(plain_content['datas'], (('1', '11'), ))

    def test_batch_with_valid_collection(self):
        message = self.request_message('BATCH',
                                       args=[
                                           [(SIGNAL_BATCH_PUT, 'a', 'a'),
                                            (SIGNAL_BATCH_PUT, 'b', 'b'),
                                            (SIGNAL_BATCH_PUT, 'c', 'c')],
                                       ])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_batch_with_invalid_signals(self):
        message = self.request_message('BATCH', [
            [(-5, 'a', 'a'), (-5, 'b', 'b'), (-5, 'c', 'c')],
        ])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], SIGNAL_ERROR)

    def test_batch_with_invalid_collection_datas_type(self):
        message = self.request_message('BATCH', [
            [(SIGNAL_BATCH_PUT, 'a', 1), (SIGNAL_BATCH_PUT, 'b', 2),
             (SIGNAL_BATCH_PUT, 'c', 3)],
        ])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], TYPE_ERROR)

    def test_connect_to_valid_database(self):
        message = Request(
            msgpack.packb({
                'uid': None,
                'cmd': 'DBCONNECT',
                'args': ['default'],
            }))
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsNotNone(plain_content)

    def test_connect_to_invalid_database(self):
        message = Request(
            msgpack.packb({
                'uid': None,
                'cmd': 'DBCONNECT',
                'args': ['dadaislikeadad']
            }))
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], DATABASE_ERROR)

    def test_connect_automatically_mounts_and_unmounted_db(self):
        # Unmount by hand the database
        db_uid = self.handler.databases.index['name_to_uid']['default']
        self.handler.databases[
            db_uid].status = self.handler.databases.STATUSES.UNMOUNTED
        self.handler.databases[db_uid].connector = None

        message = Request(
            msgpack.packb({
                'db_uid': None,
                'cmd': 'DBCONNECT',
                'args': ['default']
            }))
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(self.handler.databases[db_uid].status,
                         self.handler.databases.STATUSES.MOUNTED)
        self.assertIsInstance(self.handler.databases[db_uid].connector,
                              plyvel.DB)

    def test_create_valid_db(self):
        message = self.request_message('DBCREATE', ['testdb'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_create_already_existing_db(self):
        message = self.request_message('DBCREATE', ['default'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], DATABASE_ERROR)

    def test_drop_valid_db(self):
        message = self.request_message('DBDROP', ['default'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

        # Please teardown with something to destroy
        # MOUAHAHAHAH... Hum sorry.
        os.mkdir('/tmp/default')

    def test_drop_non_existing_db(self):
        message = self.request_message('DBDROP', ['testdb'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], DATABASE_ERROR)

    def test_list_db(self):
        message = self.request_message('DBLIST', [])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(len(plain_content), 1)
        self.assertEqual(plain_content['datas'], ('default', ))
Exemple #11
0
class DatabasesTest(unittest2.TestCase):
    def setUp(self):
        self.store = '/tmp/store.json'
        self.dest = '/tmp/dbs'
        self.config = gen_test_config()
        if not os.path.exists(self.dest):
            os.mkdir(self.dest)
        self.handler = DatabaseStore(self.config)

    def tearDown(self):
        self.handler.__del__()
        os.remove('/tmp/store.json')
        shutil.rmtree('/tmp/dbs')

    def test_init(self):
        self.assertIn('default', self.handler.index['name_to_uid'])
        default_db_uid = self.handler.index['name_to_uid']['default']

        self.assertEqual(self.handler[default_db_uid].name, 'default')
        self.assertEqual(self.handler[default_db_uid].path, '/tmp/dbs/default')

    def test_load(self):
        db_name = 'testdb'
        self.handler.add(db_name)

        self.assertIn(db_name, self.handler.index['name_to_uid'])
        db_uid = self.handler.index['name_to_uid'][db_name]

        self.assertIn(db_uid, self.handler)
        self.assertEqual(self.handler[db_uid].name, db_name)
        self.assertIn('default', self.handler.index['name_to_uid'])

    def test_store_update(self):
        db_name = 'test_db'
        db_desc = {
            'path': '/tmp/test_path',
            'uid': 'testuid',
            'options': {},
        }
        self.handler.store_update(db_name, db_desc)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_name, store_datas)
        self.assertEqual(store_datas[db_name], db_desc)

    def test_store_remove(self):
        db_name = 'test_db'
        db_desc = {
            'path': '/tmp/test_path',
            'uid': 'testuid',
            'options': {},
        }
        self.handler.store_update(db_name, db_desc)
        self.handler.store_remove(db_name)
        store_datas = json.load(open(self.handler.store_file, 'r'))

        self.assertNotIn(db_name, store_datas)

    def test_drop_existing_db(self):
        db_name = 'default'  # Automatically created on startup
        status, content = self.handler.drop(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertNotIn(db_name, store_datas)

    def test_remove_existing_db_which_files_were_erased(self):
        db_name = 'testdb'  # Automatically created on startup
        db_path = '/tmp/dbs/testdb'
        status, content = self.handler.add(db_name)
        shutil.rmtree(db_path)
        status, content = self.handler.drop(db_name)

        self.assertEqual(status, FAILURE_STATUS)
        self.assertIsInstance(content, list)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertNotIn(db_name, store_datas)

    def test_add_from_db_name_without_options_passed(self):
        db_name = 'testdb'
        default_db_options = DatabaseOptions()
        status, content = self.handler.add(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_name, store_datas)
        self.assertEqual(store_datas[db_name]["path"],
                         os.path.join(self.dest, db_name))

        self.assertIsNotNone(store_datas[db_name]["uid"])

        stored_db_options = store_datas[db_name]["options"]
        self.assertIsNotNone(stored_db_options)
        self.assertIsInstance(stored_db_options, dict)

        for option_name, option_value in default_db_options.iteritems():
            self.assertIn(option_name, stored_db_options)
            self.assertEqual(option_value, stored_db_options[option_name])

    def test_add_from_db_name_with_options_passed(self):
        db_name = 'testdb'
        db_options = DatabaseOptions(paranoid_checks=True)
        status, content = self.handler.add(db_name, db_options)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_name, store_datas)
        self.assertEqual(store_datas[db_name]["path"],
                         os.path.join(self.dest, db_name))

        self.assertIsNotNone(store_datas[db_name]["uid"])

        stored_db_options = store_datas[db_name]["options"]
        self.assertIsNotNone(stored_db_options)
        self.assertIsInstance(stored_db_options, dict)

        for option_name, option_value in db_options.iteritems():
            if option_name == "paranoid_check":
                self.assertEqual(option_value, False)
                continue
            self.assertIn(option_name, stored_db_options)
            self.assertEqual(option_value, stored_db_options[option_name])

    def test_add_from_db_abspath(self):
        db_path = '/tmp/dbs/testdb'  # Could be anywhere on fs
        default_db_options = DatabaseOptions()
        status, content = self.handler.add(db_path)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_path, store_datas)
        self.assertEqual(store_datas[db_path]["path"],
                         os.path.join(self.dest, db_path))

        self.assertIsNotNone(store_datas[db_path]["uid"])

        stored_db_options = store_datas[db_path]["options"]
        self.assertIsNotNone(stored_db_options)
        self.assertIsInstance(stored_db_options, dict)

        for option_name, option_value in default_db_options.iteritems():
            self.assertIn(option_name, stored_db_options)
            self.assertEqual(option_value, stored_db_options[option_name])

    def test_add_from_db_relpath(self):
        db_path = './testdb'  # Could be anywhere on fs
        status, content = self.handler.add(db_path)

        self.assertEqual(status, FAILURE_STATUS)
        self.assertIsInstance(content, list)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertNotIn(db_path, store_datas)

    def test_add_db_mounts_it_automatically(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        self.assertEqual(self.handler[db_uid].status, Database.STATUS.MOUNTED)
        self.assertIsNotNone(self.handler[db_uid].connector)
        self.assertIsInstance(self.handler[db_uid].connector, plyvel.DB)

    def test_mount_unmounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]
        # Unmount the db by hand
        self.handler[db_uid].status = self.handler.STATUSES.UNMOUNTED
        self.handler[db_uid].connector = None

        # Re-mount it and assert everything went fine
        status, content = self.handler.mount(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(self.handler[db_uid].status, self.handler.STATUSES.MOUNTED)
        self.assertIsNotNone(self.handler[db_uid].connector)
        self.assertIsInstance(self.handler[db_uid].connector, plyvel.DB)

    def test_mount_already_mounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)

        status, content = self.handler.mount(db_name)
        self.assertEqual(status, FAILURE_STATUS)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

    def test_mount_corrupted_db(self):
        db_name = 'testdb'
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        # Intetionaly rm db MANIFEST in order for a corruption
        # to appear.
        rm_from_pattern(self.handler[db_uid].path, 'MANIFEST*')

        status, content = self.handler.mount(db_name)
        self.assertEqual(status, FAILURE_STATUS)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

    def test_unmount_mounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        # Re-mount it and assert everything went fine
        status, content = self.handler.umount(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(self.handler[db_uid].status, self.handler.STATUSES.UNMOUNTED)
        self.assertIsNone(self.handler[db_uid].connector)

    def test_umount_already_unmounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        # Unmount the db by hand
        self.handler[db_uid].status = self.handler.STATUSES.UNMOUNTED
        self.handler[db_uid].connector = None

        status, content = self.handler.umount(db_name)
        self.assertEqual(status, FAILURE_STATUS)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)
Exemple #12
0
class ApiTests(unittest2.TestCase):
    def _bootstrap_db(self, db):
        for val in xrange(9):
            db.put(str(val), str(val + 10))

    def setUp(self):
        self.store = '/tmp/store.json'
        self.dest = '/tmp/dbs'
        self.config = gen_test_config()
        if not os.path.exists(self.dest):
            os.mkdir(self.dest)

        self.databases = DatabaseStore(self.config)
        self.default_db_uid = self.databases.index['name_to_uid']['default']
        self._bootstrap_db(self.databases[self.default_db_uid].connector)
        self.handler = Handler(self.databases)

    def tearDown(self):
        self.databases.__del__()
        del self.handler
        os.remove(self.store)
        shutil.rmtree(self.dest)

    def request_message(self, command, args, db_uid=None):
        db_uid = db_uid or self.default_db_uid
        return Request(msgpack.packb({
            'uid': db_uid,
            'cmd': command,
            'args': args,
        }))

    def test_command_with_existing_command(self):
        message = self.request_message('GET', ['1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertNotEqual(plain_content['datas'], None)

    def test_command_with_non_existing_command(self):
        message = self.request_message('COTCOT', ['testarg'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], KEY_ERROR)

    def test_command_with_invalid_db_uid(self):
        message = self.request_message('PUT', ['1', '1'], db_uid='failinguid')
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], RUNTIME_ERROR)

    def test_get_of_existing_key(self):
        message = self.request_message('GET', ['1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], ('11',))

    def test_get_of_non_existing_key(self):
        message = self.request_message('GET', ['abc123'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], KEY_ERROR)

    def test_mget_of_existing_keys(self):
        message = self.request_message('MGET', [['1', '2', '3']])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], ('11', '12', '13'))

    def test_mget_of_not_fully_existing_keys(self):
        message = self.request_message('MGET', [['1', '2', 'touptoupidou']])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], WARNING_STATUS)
        self.assertEqual(len(plain_content['datas']), 3)
        self.assertEqual(plain_content['datas'], ('11', '12', None))

    def test_put_of_valid_key(self):
        message = self.request_message('PUT', ['a', '1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_put_of_invalid_value(self):
        message = self.request_message('PUT', ['a', 1])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], TYPE_ERROR)

    def test_delete(self):
        message = self.request_message('DELETE', ['9'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_exists_of_existing_key(self):
        message = self.request_message('EXISTS', ['1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], True)

    def test_exists_of_non_existing_key_1(self):
        message = self.request_message('EXISTS', ['0'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], False)

    def test_exists_of_non_existing_key_2(self):
        message = self.request_message('EXISTS', ['non_existing'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], False)

    def test_range(self):
        message = self.request_message('RANGE', ['1', '2'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(plain_content['datas'][0], ('1', '11'))
        self.assertEqual(plain_content['datas'][1], ('2', '12'))

    def test_range_with_keys_only(self):
        message = self.request_message('RANGE', ['1', '2', True, False])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)

        self.assertEqual(len(plain_content['datas'][0]), 1)
        self.assertEqual(len(plain_content['datas'][1]), 1)

        self.assertEqual(plain_content['datas'][0], ('1'))
        self.assertEqual(plain_content['datas'][1], ('2'))

    def test_range_of_len_one(self):
        """Should still return a tuple of tuple"""
        message = self.request_message('RANGE', ['1', '1'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(len(plain_content), 1)
        self.assertEqual(plain_content['datas'], (('1', '11'),))

    def test_slice_with_limit(self):
        message = self.request_message('SLICE', ['1', 3])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(len(plain_content['datas']), 3)
        self.assertEqual(plain_content['datas'][0], ('1', '11'))
        self.assertEqual(plain_content['datas'][1], ('2', '12'))
        self.assertEqual(plain_content['datas'][2], ('3', '13'))

    def test_slice_with_limit_value_of_one(self):
        message = self.request_message('SLICE', ['1', 1])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsInstance(plain_content['datas'], tuple)
        self.assertEqual(len(plain_content), 1)
        self.assertEqual(plain_content['datas'], (('1', '11'),))

    def test_batch_with_valid_collection(self):
        message = self.request_message('BATCH', args=[
            [(SIGNAL_BATCH_PUT, 'a', 'a'),
             (SIGNAL_BATCH_PUT, 'b', 'b'),
             (SIGNAL_BATCH_PUT, 'c', 'c')],
        ])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_batch_with_invalid_signals(self):
        message = self.request_message('BATCH', [
            [(-5, 'a', 'a'),
             (-5, 'b', 'b'),
             (-5, 'c', 'c')],
        ])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], SIGNAL_ERROR)

    def test_batch_with_invalid_collection_datas_type(self):
        message = self.request_message('BATCH', [
            [(SIGNAL_BATCH_PUT, 'a', 1),
             (SIGNAL_BATCH_PUT, 'b', 2),
             (SIGNAL_BATCH_PUT, 'c', 3)],
        ])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], TYPE_ERROR)

    def test_connect_to_valid_database(self):
        message = Request(msgpack.packb({
            'uid': None,
            'cmd': 'DBCONNECT',
            'args': ['default'],
        }))
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertIsNotNone(plain_content)

    def test_connect_to_invalid_database(self):
        message = Request(msgpack.packb({
                'uid': None,
                'cmd': 'DBCONNECT',
                'args': ['dadaislikeadad']
        }))
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], DATABASE_ERROR)

    def test_connect_automatically_mounts_and_unmounted_db(self):
        # Unmount by hand the database
        db_uid = self.handler.databases.index['name_to_uid']['default']
        self.handler.databases[db_uid].status = self.handler.databases.STATUSES.UNMOUNTED
        self.handler.databases[db_uid].connector = None

        message = Request(msgpack.packb({
                'db_uid': None,
                'cmd': 'DBCONNECT',
                'args': ['default']
        }))
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(self.handler.databases[db_uid].status, self.handler.databases.STATUSES.MOUNTED)
        self.assertIsInstance(self.handler.databases[db_uid].connector, plyvel.DB)

    def test_create_valid_db(self):
        message = self.request_message('DBCREATE', ['testdb'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

    def test_create_already_existing_db(self):
        message = self.request_message('DBCREATE', ['default'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], DATABASE_ERROR)

    def test_drop_valid_db(self):
        message = self.request_message('DBDROP', ['default'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(plain_content['datas'], None)

        # Please teardown with something to destroy
        # MOUAHAHAHAH... Hum sorry.
        os.mkdir('/tmp/default')

    def test_drop_non_existing_db(self):
        message = self.request_message('DBDROP', ['testdb'])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        self.assertEqual(plain_header['status'], FAILURE_STATUS)
        self.assertEqual(plain_header['err_code'], DATABASE_ERROR)

    def test_list_db(self):
        message = self.request_message('DBLIST', [])
        header, content = self.handler.command(message)

        plain_header = msgpack.unpackb(header)
        plain_content = msgpack.unpackb(content)

        self.assertEqual(plain_header['status'], SUCCESS_STATUS)
        self.assertEqual(len(plain_content), 1)
        self.assertEqual(plain_content['datas'], ('default',))
Exemple #13
0
class DatabasesTest(unittest2.TestCase):
    def setUp(self):
        self.store = '/tmp/store.json'
        self.dest = '/tmp/dbs'
        self.config = gen_test_config()
        if not os.path.exists(self.dest):
            os.mkdir(self.dest)
        self.handler = DatabaseStore(self.config)

    def tearDown(self):
        self.handler.__del__()
        os.remove('/tmp/store.json')
        shutil.rmtree('/tmp/dbs')

    def test_init(self):
        self.assertIn('default', self.handler.index['name_to_uid'])
        default_db_uid = self.handler.index['name_to_uid']['default']

        self.assertEqual(self.handler[default_db_uid].name, 'default')
        self.assertEqual(self.handler[default_db_uid].path, '/tmp/dbs/default')

    def test_load(self):
        db_name = 'testdb'
        self.handler.add(db_name)

        self.assertIn(db_name, self.handler.index['name_to_uid'])
        db_uid = self.handler.index['name_to_uid'][db_name]

        self.assertIn(db_uid, self.handler)
        self.assertEqual(self.handler[db_uid].name, db_name)
        self.assertIn('default', self.handler.index['name_to_uid'])

    def test_store_update(self):
        db_name = 'test_db'
        db_desc = {
            'path': '/tmp/test_path',
            'uid': 'testuid',
            'options': {},
        }
        self.handler.store_update(db_name, db_desc)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_name, store_datas)
        self.assertEqual(store_datas[db_name], db_desc)

    def test_store_remove(self):
        db_name = 'test_db'
        db_desc = {
            'path': '/tmp/test_path',
            'uid': 'testuid',
            'options': {},
        }
        self.handler.store_update(db_name, db_desc)
        self.handler.store_remove(db_name)
        store_datas = json.load(open(self.handler.store_file, 'r'))

        self.assertNotIn(db_name, store_datas)

    def test_drop_existing_db(self):
        db_name = 'default'  # Automatically created on startup
        status, content = self.handler.drop(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertNotIn(db_name, store_datas)

    def test_remove_existing_db_which_files_were_erased(self):
        db_name = 'testdb'  # Automatically created on startup
        db_path = '/tmp/dbs/testdb'
        status, content = self.handler.add(db_name)
        shutil.rmtree(db_path)
        status, content = self.handler.drop(db_name)

        self.assertEqual(status, FAILURE_STATUS)
        self.assertIsInstance(content, list)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertNotIn(db_name, store_datas)

    def test_add_from_db_name_without_options_passed(self):
        db_name = 'testdb'
        default_db_options = DatabaseOptions()
        status, content = self.handler.add(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_name, store_datas)
        self.assertEqual(store_datas[db_name]["path"],
                         os.path.join(self.dest, db_name))

        self.assertIsNotNone(store_datas[db_name]["uid"])

        stored_db_options = store_datas[db_name]["options"]
        self.assertIsNotNone(stored_db_options)
        self.assertIsInstance(stored_db_options, dict)

        for option_name, option_value in default_db_options.iteritems():
            self.assertIn(option_name, stored_db_options)
            self.assertEqual(option_value, stored_db_options[option_name])

    def test_add_from_db_name_with_options_passed(self):
        db_name = 'testdb'
        db_options = DatabaseOptions(paranoid_checks=True)
        status, content = self.handler.add(db_name, db_options)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_name, store_datas)
        self.assertEqual(store_datas[db_name]["path"],
                         os.path.join(self.dest, db_name))

        self.assertIsNotNone(store_datas[db_name]["uid"])

        stored_db_options = store_datas[db_name]["options"]
        self.assertIsNotNone(stored_db_options)
        self.assertIsInstance(stored_db_options, dict)

        for option_name, option_value in db_options.iteritems():
            if option_name == "paranoid_check":
                self.assertEqual(option_value, False)
                continue
            self.assertIn(option_name, stored_db_options)
            self.assertEqual(option_value, stored_db_options[option_name])

    def test_add_from_db_abspath(self):
        db_path = '/tmp/dbs/testdb'  # Could be anywhere on fs
        default_db_options = DatabaseOptions()
        status, content = self.handler.add(db_path)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(content, None)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertIn(db_path, store_datas)
        self.assertEqual(store_datas[db_path]["path"],
                         os.path.join(self.dest, db_path))

        self.assertIsNotNone(store_datas[db_path]["uid"])

        stored_db_options = store_datas[db_path]["options"]
        self.assertIsNotNone(stored_db_options)
        self.assertIsInstance(stored_db_options, dict)

        for option_name, option_value in default_db_options.iteritems():
            self.assertIn(option_name, stored_db_options)
            self.assertEqual(option_value, stored_db_options[option_name])

    def test_add_from_db_relpath(self):
        db_path = './testdb'  # Could be anywhere on fs
        status, content = self.handler.add(db_path)

        self.assertEqual(status, FAILURE_STATUS)
        self.assertIsInstance(content, list)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

        store_datas = json.load(open(self.handler.store_file, 'r'))
        self.assertNotIn(db_path, store_datas)

    def test_add_db_mounts_it_automatically(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        self.assertEqual(self.handler[db_uid].status, Database.STATUS.MOUNTED)
        self.assertIsNotNone(self.handler[db_uid].connector)
        self.assertIsInstance(self.handler[db_uid].connector, plyvel.DB)

    def test_mount_unmounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]
        # Unmount the db by hand
        self.handler[db_uid].status = self.handler.STATUSES.UNMOUNTED
        self.handler[db_uid].connector = None

        # Re-mount it and assert everything went fine
        status, content = self.handler.mount(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(self.handler[db_uid].status,
                         self.handler.STATUSES.MOUNTED)
        self.assertIsNotNone(self.handler[db_uid].connector)
        self.assertIsInstance(self.handler[db_uid].connector, plyvel.DB)

    def test_mount_already_mounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)

        status, content = self.handler.mount(db_name)
        self.assertEqual(status, FAILURE_STATUS)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

    def test_mount_corrupted_db(self):
        db_name = 'testdb'
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        # Intetionaly rm db MANIFEST in order for a corruption
        # to appear.
        rm_from_pattern(self.handler[db_uid].path, 'MANIFEST*')

        status, content = self.handler.mount(db_name)
        self.assertEqual(status, FAILURE_STATUS)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)

    def test_unmount_mounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        # Re-mount it and assert everything went fine
        status, content = self.handler.umount(db_name)

        self.assertEqual(status, SUCCESS_STATUS)
        self.assertEqual(self.handler[db_uid].status,
                         self.handler.STATUSES.UNMOUNTED)
        self.assertIsNone(self.handler[db_uid].connector)

    def test_umount_already_unmounted_db(self):
        db_name = 'testdb'  # Automatically created on startup
        status, content = self.handler.add(db_name)
        db_uid = self.handler.index['name_to_uid'][db_name]

        # Unmount the db by hand
        self.handler[db_uid].status = self.handler.STATUSES.UNMOUNTED
        self.handler[db_uid].connector = None

        status, content = self.handler.umount(db_name)
        self.assertEqual(status, FAILURE_STATUS)
        self.assertEqual(len(content), 2)
        self.assertEqual(content[0], DATABASE_ERROR)