Quarantine malformed database schema SQLite errors
Currently if an sqlite3.DatabaseError is thrown when caused by a corrupted database schema, it get logged and the database is isn't quarantined. This patch adds the malformed database schema case to the list of SQLite errors in possibly_quarantine that will trigger the db to be quarantined. Also it improved the possibly_quarantined unit test to test all existing exceptions, and catches exceptions based on the real world except we use in code. Closes-Bug: #1646247 Change-Id: Id9452c88f8394a2a910c34c69361442543aa206d
This commit is contained in:
parent
a92836074c
commit
3bde14b5cf
@ -331,6 +331,8 @@ class DatabaseBroker(object):
|
||||
"""
|
||||
if 'database disk image is malformed' in str(exc_value):
|
||||
exc_hint = 'malformed'
|
||||
elif 'malformed database schema' in str(exc_value):
|
||||
exc_hint = 'malformed'
|
||||
elif 'file is encrypted or is not a database' in str(exc_value):
|
||||
exc_hint = 'corrupted'
|
||||
elif 'disk I/O error' in str(exc_value):
|
||||
|
BIN
test/unit/common/malformed_schema_example.db
Normal file
BIN
test/unit/common/malformed_schema_example.db
Normal file
Binary file not shown.
@ -749,6 +749,22 @@ class TestDatabaseBroker(unittest.TestCase):
|
||||
broker = DatabaseBroker(os.path.join(dbpath, '1.db'))
|
||||
broker.db_type = 'test'
|
||||
exc = None
|
||||
try:
|
||||
with broker.get() as conn:
|
||||
conn.execute('SELECT * FROM test')
|
||||
except Exception as err:
|
||||
exc = err
|
||||
self.assertEqual(
|
||||
str(exc),
|
||||
'Quarantined %s to %s due to malformed database' %
|
||||
(dbpath, qpath))
|
||||
# Test malformed schema database
|
||||
copy(os.path.join(os.path.dirname(__file__),
|
||||
'malformed_schema_example.db'),
|
||||
os.path.join(dbpath, '1.db'))
|
||||
broker = DatabaseBroker(os.path.join(dbpath, '1.db'))
|
||||
broker.db_type = 'test'
|
||||
exc = None
|
||||
try:
|
||||
with broker.get() as conn:
|
||||
conn.execute('SELECT * FROM test')
|
||||
@ -1214,29 +1230,36 @@ class TestDatabaseBroker(unittest.TestCase):
|
||||
message = str(e)
|
||||
self.assertEqual(message, '400 Bad Request')
|
||||
|
||||
def test_possibly_quarantine_disk_error(self):
|
||||
def test_possibly_quarantine_db_errors(self):
|
||||
dbpath = os.path.join(self.testdir, 'dev', 'dbs', 'par', 'pre', 'db')
|
||||
mkdirs(dbpath)
|
||||
qpath = os.path.join(self.testdir, 'dev', 'quarantined', 'tests', 'db')
|
||||
broker = DatabaseBroker(os.path.join(dbpath, '1.db'))
|
||||
broker.db_type = 'test'
|
||||
# Data is a list of Excpetions to be raised and expected values in the
|
||||
# log
|
||||
data = [
|
||||
(sqlite3.DatabaseError('database disk image is malformed'),
|
||||
'malformed'),
|
||||
(sqlite3.DatabaseError('malformed database schema'), 'malformed'),
|
||||
(sqlite3.DatabaseError('file is encrypted or is not a database'),
|
||||
'corrupted'),
|
||||
(sqlite3.OperationalError('disk I/O error'),
|
||||
'disk error while accessing')]
|
||||
|
||||
def stub():
|
||||
raise sqlite3.OperationalError('disk I/O error')
|
||||
|
||||
try:
|
||||
stub()
|
||||
except Exception:
|
||||
for i, (ex, hint) in enumerate(data):
|
||||
mkdirs(dbpath)
|
||||
broker = DatabaseBroker(os.path.join(dbpath, '%d.db' % (i)))
|
||||
broker.db_type = 'test'
|
||||
try:
|
||||
broker.possibly_quarantine(*sys.exc_info())
|
||||
except Exception as exc:
|
||||
self.assertEqual(
|
||||
str(exc),
|
||||
'Quarantined %s to %s due to disk error '
|
||||
'while accessing database' %
|
||||
(dbpath, qpath))
|
||||
else:
|
||||
self.fail('Expected an exception to be raised')
|
||||
raise ex
|
||||
except (sqlite3.DatabaseError, DatabaseConnectionError):
|
||||
try:
|
||||
broker.possibly_quarantine(*sys.exc_info())
|
||||
except Exception as exc:
|
||||
self.assertEqual(
|
||||
str(exc),
|
||||
'Quarantined %s to %s due to %s database' %
|
||||
(dbpath, qpath, hint))
|
||||
else:
|
||||
self.fail('Expected an exception to be raised')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user