Fix cinderlib tests

The persistence tests were broken when run with zed cinder.

Co-authored-by: Rajat Dhasmana <rajatdhasmana@gmail.com>
Co-authored-by: Brian Rosmaita <rosmaita.fossdev@gmail.com>

Change-Id: I4981ad558195895341c91fa37803713c8c0ab684
Closes-bug: #1996738
This commit is contained in:
Rajat Dhasmana 2022-12-09 23:32:54 +05:30 committed by Brian Rosmaita
parent b1db48c6ed
commit 728b933bf2
5 changed files with 147 additions and 22 deletions

View File

@ -180,7 +180,7 @@ class DBPersistence(persistence_base.PersistenceDriverBase):
return result
def _get_kv(self, key=None, session=None):
session = session or sqla_api.get_session()
session = objects.CONTEXT.session
query = session.query(KeyValue)
if key is not None:
query = query.filter_by(key=key)
@ -301,12 +301,11 @@ class DBPersistence(persistence_base.PersistenceDriverBase):
super(DBPersistence, self).set_connection(connection)
def set_key_value(self, key_value):
session = sqla_api.get_session()
with session.begin():
kv = self._get_kv(key_value.key, session)
kv = kv[0] if kv else KeyValue(key=key_value.key)
kv.value = key_value.value
session.add(kv)
session = objects.CONTEXT.session
kv = self._get_kv(key_value.key, session)
kv = kv[0] if kv else KeyValue(key=key_value.key)
kv.value = key_value.value
session.add(kv)
def delete_volume(self, volume):
delete_type = (volume.volume_type_id != self.DEFAULT_TYPE.id
@ -372,7 +371,8 @@ class DBPersistence(persistence_base.PersistenceDriverBase):
super(DBPersistence, self).delete_connection(connection)
def delete_key_value(self, key_value):
query = sqla_api.get_session().query(KeyValue)
session = objects.CONTEXT.session
query = session.query(KeyValue)
query.filter_by(key=key_value.key).delete()

View File

@ -27,6 +27,8 @@ class BasePersistenceTest(helper.TestHelper):
def setUp(self):
super(BasePersistenceTest, self).setUp()
self.backend_name = 'fake_backend'
self.backend = utils.FakeBackend(volume_backend_name=self.backend_name)
def assertListEqualObj(self, expected, actual):
exp = [self._convert_to_dict(e) for e in expected]

View File

@ -69,7 +69,12 @@ class TestHelper(base.BaseTest):
d.setdefault('backend_or_vol', self.backend)
vol = cinderlib.Volume(**d)
vols.append(vol)
self.persistence.set_volume(vol)
# db_instance is a property of DBMS plugin
if hasattr(self.persistence, 'db_instance'):
with api.main_context_manager.writer.using(self.context):
self.persistence.set_volume(vol)
else:
self.persistence.set_volume(vol)
if sort:
return self.sorted(vols)
return vols
@ -98,7 +103,12 @@ class TestHelper(base.BaseTest):
for i in range(2):
kv = cinderlib.KeyValue(key='key%i' % i, value='value%i' % i)
kvs.append(kv)
self.persistence.set_key_value(kv)
# db_instance is a property of DBMS plugin
if hasattr(self.persistence, 'db_instance'):
with api.main_context_manager.writer.using(self.context):
self.persistence.set_key_value(kv)
else:
self.persistence.set_key_value(kv)
return kvs
def _convert_to_dict(self, obj):

View File

@ -32,11 +32,14 @@ class TestDBPersistence(base.BasePersistenceTest):
'connection': CONNECTION}
def tearDown(self):
sqla_api.model_query(self.context, sqla_models.Snapshot).delete()
sqla_api.model_query(self.context,
sqla_models.VolumeAttachment).delete()
sqla_api.model_query(self.context, sqla_models.Volume).delete()
sqla_api.get_session().query(dbms.KeyValue).delete()
with sqla_api.main_context_manager.writer.using(self.context):
sqla_api.model_query(self.context, sqla_models.Snapshot).delete()
sqla_api.model_query(self.context,
sqla_models.VolumeAttachment).delete()
sqla_api.model_query(self.context, sqla_models.Volume).delete()
self.context.session.query(dbms.KeyValue).delete()
# FIXME: should this be inside or outside the context manager?
# Doesn't seem to matter for our current tests.
super(TestDBPersistence, self).tearDown()
def test_db(self):
@ -98,13 +101,16 @@ class TestDBPersistence(base.BasePersistenceTest):
self.assertEqualObj(conn, cl_conn)
def test_set_key_values(self):
res = sqla_api.get_session().query(dbms.KeyValue).all()
with sqla_api.main_context_manager.reader.using(self.context):
res = self.context.session.query(dbms.KeyValue).all()
self.assertListEqual([], res)
expected = [dbms.KeyValue(key='key', value='value')]
self.persistence.set_key_value(expected[0])
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.set_key_value(expected[0])
actual = sqla_api.get_session().query(dbms.KeyValue).all()
with sqla_api.main_context_manager.reader.using(self.context):
actual = self.context.session.query(dbms.KeyValue).all()
self.assertListEqualObj(expected, actual)
def test_create_volume_with_default_volume_type(self):
@ -122,20 +128,120 @@ class TestDBPersistence(base.BasePersistenceTest):
self.assertEqual('__DEFAULT__', self.persistence.DEFAULT_TYPE.name)
def test_delete_volume_with_metadata(self):
# FIXME: figure out why this sometimes (often enough to skip)
# raises sqlite3.OperationalError: database is locked
if not isinstance(self, TestMemoryDBPersistence):
self.skipTest("FIXME!")
vols = self.create_volumes([{'size': i, 'name': 'disk%s' % i,
'metadata': {'k': 'v', 'k2': 'v2'},
'admin_metadata': {'k': '1'}}
for i in range(1, 3)])
self.persistence.delete_volume(vols[0])
res = self.persistence.get_volumes()
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_volume(vols[0])
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_volumes()
self.assertListEqualObj([vols[1]], res)
for model in (dbms.models.VolumeMetadata,
dbms.models.VolumeAdminMetadata):
query = dbms.sqla_api.model_query(self.context, model)
with sqla_api.main_context_manager.reader.using(self.context):
query = dbms.sqla_api.model_query(self.context, model)
res = query.filter_by(volume_id=vols[0].id).all()
self.assertEqual([], res)
def test_delete_volume(self):
vols = self.create_n_volumes(2)
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_volume(vols[0])
res = self.persistence.get_volumes()
self.assertListEqualObj([vols[1]], res)
def test_delete_volume_not_found(self):
vols = self.create_n_volumes(2)
fake_vol = cinderlib.Volume(backend_or_vol=self.backend)
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_volume(fake_vol)
res = self.persistence.get_volumes()
self.assertListEqualObj(vols, self.sorted(res))
def test_get_snapshots_by_multiple_not_found(self):
with sqla_api.main_context_manager.writer.using(self.context):
snaps = self.create_snapshots()
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_snapshots(snapshot_name=snaps[1].name,
volume_id=snaps[0].volume.id)
self.assertListEqualObj([], res)
def test_delete_snapshot(self):
with sqla_api.main_context_manager.writer.using(self.context):
snaps = self.create_snapshots()
self.persistence.delete_snapshot(snaps[0])
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_snapshots()
self.assertListEqualObj([snaps[1]], res)
def test_delete_snapshot_not_found(self):
with sqla_api.main_context_manager.writer.using(self.context):
snaps = self.create_snapshots()
fake_snap = cinderlib.Snapshot(snaps[0].volume)
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_snapshot(fake_snap)
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_snapshots()
self.assertListEqualObj(snaps, self.sorted(res))
def test_delete_connection(self):
conns = self.create_connections()
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_connection(conns[1])
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_connections()
self.assertListEqualObj([conns[0]], res)
def test_delete_connection_not_found(self):
conns = self.create_connections()
fake_conn = cinderlib.Connection(
self.backend,
volume=conns[0].volume,
connection_info={'conn': {'data': {}}})
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_connection(fake_conn)
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_connections()
self.assertListEqualObj(conns, self.sorted(res))
def test_get_key_values_by_key(self):
with sqla_api.main_context_manager.writer.using(self.context):
kvs = self.create_key_values()
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_key_values(key=kvs[1].key)
self.assertListEqual([kvs[1]], res)
def test_get_key_values_by_key_not_found(self):
with sqla_api.main_context_manager.writer.using(self.context):
self.create_key_values()
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_key_values(key='fake-uuid')
self.assertListEqual([], res)
def test_delete_key_value(self):
kvs = self.create_key_values()
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_key_value(kvs[1])
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_key_values()
self.assertListEqual([kvs[0]], res)
def test_delete_key_not_found(self):
kvs = self.create_key_values()
fake_key = cinderlib.KeyValue('fake-key')
with sqla_api.main_context_manager.writer.using(self.context):
self.persistence.delete_key_value(fake_key)
with sqla_api.main_context_manager.reader.using(self.context):
res = self.persistence.get_key_values()
self.assertListEqual(kvs, self.sorted(res, 'key'))
class TestDBPersistenceNewerSchema(base.helper.TestHelper):
"""Test DBMS plugin can start when the DB has a newer schema."""

View File

@ -36,7 +36,14 @@ deps =
commands =
find . -ignore_readdir_race -type f -name "*.pyc" -delete
stestr run {posargs}
# FIXME: figure out why these need to be run in extreme isolation
stestr run --exclude-regex cinderlib.tests.unit.persistence.test_dbms {posargs}
stestr run --combine {posargs} cinderlib.tests.unit.persistence.test_dbms.TestDBPersistence
stestr run --combine {posargs} cinderlib.tests.unit.persistence.test_dbms.TestMemoryDBPersistence
# TODO: figure out how to arrange the above so that you can run a
# a single test. For example, invoking
# tox -e py310 -- cinderlib.tests.unit.test_cinderlib.TestCinderlib.test__set_priv_helper
# runs that test and then TestDBPersistence tests and then TestMemoryDBPersistence tests
stestr slowest
allowlist_externals =