summaryrefslogtreecommitdiff
path: root/nova
diff options
context:
space:
mode:
authorStephen Finucane <sfinucan@redhat.com>2022-04-08 10:58:42 +0100
committerStephen Finucane <sfinucan@redhat.com>2022-04-08 15:57:06 +0100
commit612b83ee5dfe426a9bb9771d0e55cc13209565d5 (patch)
tree45b4e8aeb5e38d864207a7caca5175bb89246150 /nova
parentb02166c91f0b55d265a684008108e1b21cf609a4 (diff)
downloadnova-612b83ee5dfe426a9bb9771d0e55cc13209565d5.tar.gz
db: Don't rely on autocommit behavior
Resolve the following RemovedIn20Warning warning: The current statement is being autocommitted using implicit autocommit, which will be removed in SQLAlchemy 2.0. Use the .begin() method of Engine or Connection in order to use an explicit transaction for DML and DDL statements. I genuinely expected this one to be more difficult to resolve, but we weren't using this as much as expected (thank you, non-legacy enginefacade). With this change, we appear to be SQLAlchemy 2.0 ready. Change-Id: Ic43c21038ee682f9733fbde42c6d24f8088815fc Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
Diffstat (limited to 'nova')
-rw-r--r--nova/db/main/api.py28
-rw-r--r--nova/tests/fixtures/nova.py9
-rw-r--r--nova/tests/unit/db/main/test_api.py473
-rw-r--r--nova/tests/unit/objects/test_instance.py14
4 files changed, 309 insertions, 215 deletions
diff --git a/nova/db/main/api.py b/nova/db/main/api.py
index 5ef693cbac..d33bbc242f 100644
--- a/nova/db/main/api.py
+++ b/nova/db/main/api.py
@@ -612,9 +612,9 @@ def _compute_node_select(context, filters=None, limit=None, marker=None):
def _compute_node_fetchall(context, filters=None, limit=None, marker=None):
select = _compute_node_select(context, filters, limit=limit, marker=marker)
engine = get_engine(context=context)
- conn = engine.connect()
- results = conn.execute(select).fetchall()
+ with engine.connect() as conn, conn.begin():
+ results = conn.execute(select).fetchall()
# Callers expect dict-like objects, not SQLAlchemy RowProxy objects...
results = [dict(r._mapping) for r in results]
@@ -983,9 +983,9 @@ def compute_node_statistics(context):
).label('disk_available_least'),
]
select = sql.select(*agg_cols).select_from(j)
- conn = engine.connect()
- results = conn.execute(select).fetchone()
+ with engine.connect() as conn, conn.begin():
+ results = conn.execute(select).fetchone()
# Build a dict of the info--making no assumptions about result
fields = ('count', 'vcpus', 'memory_mb', 'local_gb', 'vcpus_used',
@@ -993,7 +993,6 @@ def compute_node_statistics(context):
'current_workload', 'running_vms', 'disk_available_least')
results = {field: int(results[idx] or 0)
for idx, field in enumerate(fields)}
- conn.close()
return results
@@ -4293,7 +4292,8 @@ def _get_fk_stmts(metadata, conn, table, column, records):
select = sql.select(fk.column).where(
sql.and_(fk.parent == fk.column, column.in_(records))
)
- rows = conn.execute(select).fetchall()
+ with conn.begin():
+ rows = conn.execute(select).fetchall()
p_records = [r[0] for r in rows]
# Then, select rows in the child table that correspond to the
# parent table records that were passed in.
@@ -4308,7 +4308,8 @@ def _get_fk_stmts(metadata, conn, table, column, records):
fk_select = sql.select(fk_column).where(
sql.and_(fk.parent == fk.column, fk.column.in_(p_records))
)
- fk_rows = conn.execute(fk_select).fetchall()
+ with conn.begin():
+ fk_rows = conn.execute(fk_select).fetchall()
fk_records = [r[0] for r in fk_rows]
if fk_records:
# If we found any records in the child table, create shadow
@@ -4395,7 +4396,8 @@ def _archive_deleted_rows_for_table(
select = select.where(table.c.updated_at < before)
select = select.order_by(column).limit(max_rows)
- rows = conn.execute(select).fetchall()
+ with conn.begin():
+ rows = conn.execute(select).fetchall()
records = [r[0] for r in rows]
# We will archive deleted rows for this table and also generate insert and
@@ -4431,7 +4433,8 @@ def _archive_deleted_rows_for_table(
query_select = sql.select(table.c.uuid).where(
table.c.id.in_(records)
)
- rows = conn.execute(query_select).fetchall()
+ with conn.begin():
+ rows = conn.execute(query_select).fetchall()
deleted_instance_uuids = [r[0] for r in rows]
try:
@@ -4453,6 +4456,8 @@ def _archive_deleted_rows_for_table(
"%(tablename)s: %(error)s",
{'tablename': tablename, 'error': str(ex)})
+ conn.close()
+
return rows_archived, deleted_instance_uuids, extras
@@ -4575,7 +4580,8 @@ def purge_shadow_tables(context, before_date, status_fn=None):
else:
delete = table.delete()
- deleted = conn.execute(delete)
+ with conn.begin():
+ deleted = conn.execute(delete)
if deleted.rowcount > 0:
status_fn(_('Deleted %(rows)i rows from %(table)s based on '
'timestamp column %(col)s') % {
@@ -4584,6 +4590,8 @@ def purge_shadow_tables(context, before_date, status_fn=None):
'col': col is None and '(n/a)' or col.name})
total_deleted += deleted.rowcount
+ conn.close()
+
return total_deleted
diff --git a/nova/tests/fixtures/nova.py b/nova/tests/fixtures/nova.py
index 527e339aed..ee21ab9f2b 100644
--- a/nova/tests/fixtures/nova.py
+++ b/nova/tests/fixtures/nova.py
@@ -870,15 +870,6 @@ class WarningsFixture(fixtures.Fixture):
category=sqla_exc.SADeprecationWarning,
)
- # ...but filter everything out until we get around to fixing them
- # TODO(stephenfin): Fix all of these
-
- warnings.filterwarnings(
- 'ignore',
- module='nova',
- message=r'The current statement is being autocommitted .*',
- category=sqla_exc.SADeprecationWarning)
-
self.addCleanup(self._reset_warning_filters)
def _reset_warning_filters(self):
diff --git a/nova/tests/unit/db/main/test_api.py b/nova/tests/unit/db/main/test_api.py
index fd1b0fd221..e0017bca17 100644
--- a/nova/tests/unit/db/main/test_api.py
+++ b/nova/tests/unit/db/main/test_api.py
@@ -5663,7 +5663,6 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
super(ArchiveTestCase, self).setUp()
self.engine = db.get_engine()
self.metadata = sa.MetaData()
- self.conn = self.engine.connect()
self.instance_id_mappings = models.InstanceIdMapping.__table__
self.shadow_instance_id_mappings = sqlalchemyutils.get_table(
self.engine, "shadow_instance_id_mappings")
@@ -5696,12 +5695,13 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
"""
metadata = sa.MetaData()
metadata.reflect(bind=self.engine)
- for table in metadata.tables:
- if table.startswith("shadow_") and table not in exceptions:
- rows = self.conn.exec_driver_sql(
- "SELECT * FROM %s" % table
- ).fetchall()
- self.assertEqual(rows, [], "Table %s not empty" % table)
+ with self.engine.connect() as conn, conn.begin():
+ for table in metadata.tables:
+ if table.startswith("shadow_") and table not in exceptions:
+ rows = conn.exec_driver_sql(
+ "SELECT * FROM %s" % table
+ ).fetchall()
+ self.assertEqual(rows, [], "Table %s not empty" % table)
def test_shadow_tables(self):
"""Validate shadow table schema.
@@ -5754,57 +5754,72 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
self._assert_shadow_tables_empty_except()
def test_archive_deleted_rows(self):
- # Add 6 rows to table
- for uuidstr in self.uuidstrs:
- ins_stmt = self.instance_id_mappings.insert().values(uuid=uuidstr)
- self.conn.execute(ins_stmt)
+ with self.engine.connect() as conn, conn.begin():
+ # Add 6 rows to table
+ for uuidstr in self.uuidstrs:
+ ins_stmt = self.instance_id_mappings.insert().values(
+ uuid=uuidstr,
+ )
+ conn.execute(ins_stmt)
+
# Set 4 to deleted
- update_statement = self.instance_id_mappings.update().\
- where(self.instance_id_mappings.c.uuid.in_(self.uuidstrs[:4]))\
- .values(deleted=1, deleted_at=timeutils.utcnow())
- self.conn.execute(update_statement)
+ with self.engine.connect() as conn, conn.begin():
+ update_statement = self.instance_id_mappings.update().where(
+ self.instance_id_mappings.c.uuid.in_(self.uuidstrs[:4])
+ ).values(deleted=1, deleted_at=timeutils.utcnow())
+ conn.execute(update_statement)
+
qiim = sql.select(self.instance_id_mappings).where(
self.instance_id_mappings.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qiim).fetchall()
- # Verify we have 6 in main
- self.assertEqual(len(rows), 6)
qsiim = sql.select(self.shadow_instance_id_mappings).where(
self.shadow_instance_id_mappings.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qsiim).fetchall()
- # Verify we have 0 in shadow
- self.assertEqual(len(rows), 0)
- # Archive 2 rows
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 6 in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 6)
+ # Verify we have 0 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 0)
+
results = db.archive_deleted_rows(max_rows=2)
expected = dict(instance_id_mappings=2)
self._assertEqualObjects(expected, results[0])
- rows = self.conn.execute(qiim).fetchall()
- # Verify we have 4 left in main
- self.assertEqual(len(rows), 4)
- rows = self.conn.execute(qsiim).fetchall()
- # Verify we have 2 in shadow
- self.assertEqual(len(rows), 2)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Archive 2 rows and verify we have 4 left in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 4)
+ # Verify we have 2 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 2)
# Archive 2 more rows
results = db.archive_deleted_rows(max_rows=2)
expected = dict(instance_id_mappings=2)
self._assertEqualObjects(expected, results[0])
- rows = self.conn.execute(qiim).fetchall()
- # Verify we have 2 left in main
- self.assertEqual(len(rows), 2)
- rows = self.conn.execute(qsiim).fetchall()
- # Verify we have 4 in shadow
- self.assertEqual(len(rows), 4)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 2 left in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 2)
+ # Verify we have 4 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 4)
+
# Try to archive more, but there are no deleted rows left.
results = db.archive_deleted_rows(max_rows=2)
expected = dict()
self._assertEqualObjects(expected, results[0])
- rows = self.conn.execute(qiim).fetchall()
- # Verify we still have 2 left in main
- self.assertEqual(len(rows), 2)
- rows = self.conn.execute(qsiim).fetchall()
- # Verify we still have 4 in shadow
- self.assertEqual(len(rows), 4)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we still have 2 left in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 2)
+ # Verify we still have 4 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 4)
# Ensure only deleted rows were deleted
self._assert_shadow_tables_empty_except(
@@ -5814,34 +5829,45 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
# Add 6 rows to table
for uuidstr in self.uuidstrs:
ins_stmt = self.instances.insert().values(uuid=uuidstr)
- self.conn.execute(ins_stmt)
- ins_stmt = self.instance_actions.insert().\
- values(instance_uuid=uuidstr)
- result = self.conn.execute(ins_stmt)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
+
+ ins_stmt = self.instance_actions.insert().values(
+ instance_uuid=uuidstr,
+ )
+ with self.engine.connect() as conn, conn.begin():
+ result = conn.execute(ins_stmt)
+
instance_action_uuid = result.inserted_primary_key[0]
- ins_stmt = self.instance_actions_events.insert().\
- values(action_id=instance_action_uuid)
- self.conn.execute(ins_stmt)
+ ins_stmt = self.instance_actions_events.insert().values(
+ action_id=instance_action_uuid,
+ )
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
# Set 1 to deleted before 2017-01-01
deleted_at = timeutils.parse_strtime('2017-01-01T00:00:00.0')
- update_statement = self.instances.update().\
- where(self.instances.c.uuid.in_(self.uuidstrs[0:1]))\
- .values(deleted=1, deleted_at=deleted_at)
- self.conn.execute(update_statement)
+ update_statement = self.instances.update().where(
+ self.instances.c.uuid.in_(self.uuidstrs[0:1])
+ ).values(deleted=1, deleted_at=deleted_at)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
# Set 1 to deleted before 2017-01-02
deleted_at = timeutils.parse_strtime('2017-01-02T00:00:00.0')
- update_statement = self.instances.update().\
- where(self.instances.c.uuid.in_(self.uuidstrs[1:2]))\
- .values(deleted=1, deleted_at=deleted_at)
- self.conn.execute(update_statement)
+ update_statement = self.instances.update().where(
+ self.instances.c.uuid.in_(self.uuidstrs[1:2])
+ ).values(deleted=1, deleted_at=deleted_at)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
# Set 2 to deleted now
- update_statement = self.instances.update().\
- where(self.instances.c.uuid.in_(self.uuidstrs[2:4]))\
- .values(deleted=1, deleted_at=timeutils.utcnow())
- self.conn.execute(update_statement)
+ update_statement = self.instances.update().where(
+ self.instances.c.uuid.in_(self.uuidstrs[2:4])
+ ).values(deleted=1, deleted_at=timeutils.utcnow())
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
+
qiim = sql.select(self.instances).where(
self. instances.c.uuid.in_(self.uuidstrs)
)
@@ -5849,9 +5875,11 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
self.shadow_instances.c.uuid.in_(self.uuidstrs)
)
- # Verify we have 6 in main
- rows = self.conn.execute(qiim).fetchall()
- self.assertEqual(len(rows), 6)
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 6 in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 6)
+
# Make sure 'before' comparison is for < not <=, nothing deleted
before_date = dateutil_parser.parse('2017-01-01', fuzzy=True)
_, uuids, _ = db.archive_deleted_rows(max_rows=1, before=before_date)
@@ -5885,22 +5913,25 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
expected = {}
self._assertEqualObjects(expected, results[0])
- # Verify we have 4 left in main
- rows = self.conn.execute(qiim).fetchall()
- self.assertEqual(len(rows), 4)
- # Verify we have 2 in shadow
- rows = self.conn.execute(qsiim).fetchall()
- self.assertEqual(len(rows), 2)
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 4 left in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 4)
+ # Verify we have 2 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 2)
# Archive everything else, make sure default operation without
# before argument didn't break
results = db.archive_deleted_rows(max_rows=1000)
- # Verify we have 2 left in main
- rows = self.conn.execute(qiim).fetchall()
- self.assertEqual(len(rows), 2)
- # Verify we have 4 in shadow
- rows = self.conn.execute(qsiim).fetchall()
- self.assertEqual(len(rows), 4)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 2 left in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 2)
+ # Verify we have 4 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 4)
def test_archive_deleted_rows_for_every_uuid_table(self):
tablenames = []
@@ -5928,94 +5959,117 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
for uuidstr in self.uuidstrs:
ins_stmt = main_table.insert().values(uuid=uuidstr)
try:
- self.conn.execute(ins_stmt)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
except (db_exc.DBError, sqla_exc.OperationalError):
# This table has constraints that require a table-specific
# insert, so skip it.
return 2
# Set 4 to deleted
- update_statement = main_table.update().\
- where(main_table.c.uuid.in_(self.uuidstrs[:4]))\
- .values(deleted=1, deleted_at=timeutils.utcnow())
- self.conn.execute(update_statement)
+ update_statement = main_table.update().where(
+ main_table.c.uuid.in_(self.uuidstrs[:4])
+ ).values(deleted=1, deleted_at=timeutils.utcnow())
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
+
qmt = sql.select(main_table).where(
main_table.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qmt).fetchall()
- # Verify we have 6 in main
- self.assertEqual(len(rows), 6)
qst = sql.select(shadow_table).where(
shadow_table.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qst).fetchall()
- # Verify we have 0 in shadow
- self.assertEqual(len(rows), 0)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 6 in main
+ rows = conn.execute(qmt).fetchall()
+ self.assertEqual(len(rows), 6)
+ # Verify we have 0 in shadow
+ rows = conn.execute(qst).fetchall()
+ self.assertEqual(len(rows), 0)
+
# Archive 2 rows
db._archive_deleted_rows_for_table(
self.metadata, self.engine, tablename, max_rows=2, before=None,
task_log=False,
)
- # Verify we have 4 left in main
- rows = self.conn.execute(qmt).fetchall()
- self.assertEqual(len(rows), 4)
- # Verify we have 2 in shadow
- rows = self.conn.execute(qst).fetchall()
- self.assertEqual(len(rows), 2)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 4 left in main
+ rows = conn.execute(qmt).fetchall()
+ self.assertEqual(len(rows), 4)
+ # Verify we have 2 in shadow
+ rows = conn.execute(qst).fetchall()
+ self.assertEqual(len(rows), 2)
+
# Archive 2 more rows
db._archive_deleted_rows_for_table(
self.metadata, self.engine, tablename, max_rows=2, before=None,
task_log=False,
)
- # Verify we have 2 left in main
- rows = self.conn.execute(qmt).fetchall()
- self.assertEqual(len(rows), 2)
- # Verify we have 4 in shadow
- rows = self.conn.execute(qst).fetchall()
- self.assertEqual(len(rows), 4)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 2 left in main
+ rows = conn.execute(qmt).fetchall()
+ self.assertEqual(len(rows), 2)
+ # Verify we have 4 in shadow
+ rows = conn.execute(qst).fetchall()
+ self.assertEqual(len(rows), 4)
+
# Try to archive more, but there are no deleted rows left.
db._archive_deleted_rows_for_table(
self.metadata, self.engine, tablename, max_rows=2, before=None,
task_log=False,
)
- # Verify we still have 2 left in main
- rows = self.conn.execute(qmt).fetchall()
- self.assertEqual(len(rows), 2)
- # Verify we still have 4 in shadow
- rows = self.conn.execute(qst).fetchall()
- self.assertEqual(len(rows), 4)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we still have 2 left in main
+ rows = conn.execute(qmt).fetchall()
+ self.assertEqual(len(rows), 2)
+ # Verify we still have 4 in shadow
+ rows = conn.execute(qst).fetchall()
+ self.assertEqual(len(rows), 4)
+
return 0
def test_archive_deleted_rows_shadow_insertions_equals_deletions(self):
# Add 2 rows to table
for uuidstr in self.uuidstrs[:2]:
ins_stmt = self.instance_id_mappings.insert().values(uuid=uuidstr)
- self.conn.execute(ins_stmt)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
+
# Set both to deleted
- update_statement = self.instance_id_mappings.update().\
- where(self.instance_id_mappings.c.uuid.in_(self.uuidstrs[:2]))\
- .values(deleted=1)
- self.conn.execute(update_statement)
+ update_statement = self.instance_id_mappings.update().where(
+ self.instance_id_mappings.c.uuid.in_(self.uuidstrs[:2])
+ ).values(deleted=1)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
+
qiim = sql.select(self.instance_id_mappings).where(
self. instance_id_mappings.c.uuid.in_(self.uuidstrs[:2])
)
- rows = self.conn.execute(qiim).fetchall()
- # Verify we have 2 in main
- self.assertEqual(len(rows), 2)
-
qsiim = sql.select(self.shadow_instance_id_mappings).where(
self.shadow_instance_id_mappings.c.uuid.in_(self.uuidstrs[:2])
)
- shadow_rows = self.conn.execute(qsiim).fetchall()
- # Verify we have 0 in shadow
- self.assertEqual(len(shadow_rows), 0)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 2 in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 2)
+ # Verify we have 0 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 0)
# Archive the rows
db.archive_deleted_rows(max_rows=2)
- main_rows = self.conn.execute(qiim).fetchall()
- shadow_rows = self.conn.execute(qsiim).fetchall()
- # Verify the insertions into shadow is same as deletions from main
- self.assertEqual(len(shadow_rows), len(rows) - len(main_rows))
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we now have 0 in main
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 0)
+ # Verify we now have 2 in shadow
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 2)
def test_archive_deleted_rows_for_migrations(self):
# migrations.instance_uuid depends on instances.uuid
@@ -6025,13 +6079,18 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
instance_uuid = uuidsentinel.instance
ins_stmt = self.instances.insert().values(
- uuid=instance_uuid,
- deleted=1,
- deleted_at=timeutils.utcnow())
- self.conn.execute(ins_stmt)
- ins_stmt = self.migrations.insert().values(instance_uuid=instance_uuid,
- deleted=0)
- self.conn.execute(ins_stmt)
+ uuid=instance_uuid,
+ deleted=1,
+ deleted_at=timeutils.utcnow(),
+ )
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
+
+ ins_stmt = self.migrations.insert().values(
+ instance_uuid=instance_uuid, deleted=0,
+ )
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
# Archiving instances should result in migrations related to the
# instances also being archived.
num = db._archive_deleted_rows_for_table(
@@ -6047,70 +6106,86 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
# Add 6 rows to each table
for uuidstr in self.uuidstrs:
ins_stmt = self.instance_id_mappings.insert().values(uuid=uuidstr)
- self.conn.execute(ins_stmt)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
ins_stmt2 = self.instances.insert().values(uuid=uuidstr)
- self.conn.execute(ins_stmt2)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt2)
# Set 4 of each to deleted
update_statement = self.instance_id_mappings.update().\
where(self.instance_id_mappings.c.uuid.in_(self.uuidstrs[:4]))\
.values(deleted=1, deleted_at=timeutils.utcnow())
- self.conn.execute(update_statement)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
update_statement2 = self.instances.update().\
where(self.instances.c.uuid.in_(self.uuidstrs[:4]))\
.values(deleted=1, deleted_at=timeutils.utcnow())
- self.conn.execute(update_statement2)
- # Verify we have 6 in each main table
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement2)
+
qiim = sql.select(self.instance_id_mappings).where(
self.instance_id_mappings.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qiim).fetchall()
- self.assertEqual(len(rows), 6)
qi = sql.select(self.instances).where(
self.instances.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qi).fetchall()
- self.assertEqual(len(rows), 6)
- # Verify we have 0 in each shadow table
qsiim = sql.select(self.shadow_instance_id_mappings).where(
self.shadow_instance_id_mappings.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qsiim).fetchall()
- self.assertEqual(len(rows), 0)
qsi = sql.select(self.shadow_instances).where(
self.shadow_instances.c.uuid.in_(self.uuidstrs)
)
- rows = self.conn.execute(qsi).fetchall()
- self.assertEqual(len(rows), 0)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 6 in each main table
+ rows = conn.execute(qiim).fetchall()
+ self.assertEqual(len(rows), 6)
+ rows = conn.execute(qi).fetchall()
+ self.assertEqual(len(rows), 6)
+ # Verify we have 0 in each shadow table
+ rows = conn.execute(qsiim).fetchall()
+ self.assertEqual(len(rows), 0)
+ rows = conn.execute(qsi).fetchall()
+ self.assertEqual(len(rows), 0)
+
# Archive 7 rows, which should be 4 in one table and 3 in the other.
db.archive_deleted_rows(max_rows=7)
- # Verify we have 5 left in the two main tables combined
- iim_rows = self.conn.execute(qiim).fetchall()
- i_rows = self.conn.execute(qi).fetchall()
- self.assertEqual(len(iim_rows) + len(i_rows), 5)
- # Verify we have 7 in the two shadow tables combined.
- siim_rows = self.conn.execute(qsiim).fetchall()
- si_rows = self.conn.execute(qsi).fetchall()
- self.assertEqual(len(siim_rows) + len(si_rows), 7)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 5 left in the two main tables combined
+ iim_rows = conn.execute(qiim).fetchall()
+ i_rows = conn.execute(qi).fetchall()
+ self.assertEqual(len(iim_rows) + len(i_rows), 5)
+ # Verify we have 7 in the two shadow tables combined.
+ siim_rows = conn.execute(qsiim).fetchall()
+ si_rows = conn.execute(qsi).fetchall()
+ self.assertEqual(len(siim_rows) + len(si_rows), 7)
# Archive the remaining deleted rows.
db.archive_deleted_rows(max_rows=1)
- # Verify we have 4 total left in both main tables.
- iim_rows = self.conn.execute(qiim).fetchall()
- i_rows = self.conn.execute(qi).fetchall()
- self.assertEqual(len(iim_rows) + len(i_rows), 4)
- # Verify we have 8 in shadow
- siim_rows = self.conn.execute(qsiim).fetchall()
- si_rows = self.conn.execute(qsi).fetchall()
- self.assertEqual(len(siim_rows) + len(si_rows), 8)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 4 total left in both main tables.
+ iim_rows = conn.execute(qiim).fetchall()
+ i_rows = conn.execute(qi).fetchall()
+ self.assertEqual(len(iim_rows) + len(i_rows), 4)
+ # Verify we have 8 in shadow
+ siim_rows = conn.execute(qsiim).fetchall()
+ si_rows = conn.execute(qsi).fetchall()
+ self.assertEqual(len(siim_rows) + len(si_rows), 8)
+
# Try to archive more, but there are no deleted rows left.
db.archive_deleted_rows(max_rows=500)
- # Verify we have 4 total left in both main tables.
- iim_rows = self.conn.execute(qiim).fetchall()
- i_rows = self.conn.execute(qi).fetchall()
- self.assertEqual(len(iim_rows) + len(i_rows), 4)
- # Verify we have 8 in shadow
- siim_rows = self.conn.execute(qsiim).fetchall()
- si_rows = self.conn.execute(qsi).fetchall()
- self.assertEqual(len(siim_rows) + len(si_rows), 8)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 4 total left in both main tables.
+ iim_rows = conn.execute(qiim).fetchall()
+ i_rows = conn.execute(qi).fetchall()
+ self.assertEqual(len(iim_rows) + len(i_rows), 4)
+ # Verify we have 8 in shadow
+ siim_rows = conn.execute(qsiim).fetchall()
+ si_rows = conn.execute(qsi).fetchall()
+ self.assertEqual(len(siim_rows) + len(si_rows), 8)
+
self._assert_shadow_tables_empty_except(
'shadow_instances',
'shadow_instance_id_mappings'
@@ -6122,34 +6197,47 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
ins_stmt = self.task_log.insert().values(
id=i, task_name='instance_usage_audit', state='DONE',
host='host', message='message')
- self.conn.execute(ins_stmt)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(ins_stmt)
+
# Set 1 to updated before 2017-01-01
updated_at = timeutils.parse_strtime('2017-01-01T00:00:00.0')
update_statement = self.task_log.update().where(
- self.task_log.c.id == 1).values(updated_at=updated_at)
- self.conn.execute(update_statement)
+ self.task_log.c.id == 1
+ ).values(updated_at=updated_at)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
+
# Set 1 to updated before 2017-01-02
updated_at = timeutils.parse_strtime('2017-01-02T00:00:00.0')
update_statement = self.task_log.update().where(
- self.task_log.c.id == 2).values(updated_at=updated_at)
- self.conn.execute(update_statement)
+ self.task_log.c.id == 2
+ ).values(updated_at=updated_at)
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
+
# Set 2 to updated now
update_statement = self.task_log.update().where(
- self.task_log.c.id.in_(range(3, 5))).values(
- updated_at=timeutils.utcnow())
- self.conn.execute(update_statement)
- # Verify we have 6 in main
+ self.task_log.c.id.in_(range(3, 5))
+ ).values(updated_at=timeutils.utcnow())
+ with self.engine.connect() as conn, conn.begin():
+ conn.execute(update_statement)
+
qtl = sql.select(self.task_log).where(
self.task_log.c.id.in_(range(1, 7))
)
- rows = self.conn.execute(qtl).fetchall()
- self.assertEqual(len(rows), 6)
- # Verify we have 0 in shadow
qstl = sql.select(self.shadow_task_log).where(
self.shadow_task_log.c.id.in_(range(1, 7))
)
- rows = self.conn.execute(qstl).fetchall()
- self.assertEqual(len(rows), 0)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 6 in main
+ rows = conn.execute(qtl).fetchall()
+ self.assertEqual(len(rows), 6)
+ # Verify we have 0 in shadow
+ rows = conn.execute(qstl).fetchall()
+ self.assertEqual(len(rows), 0)
+
# Make sure 'before' comparison is for < not <=
before_date = dateutil_parser.parse('2017-01-01', fuzzy=True)
_, _, rows = db.archive_deleted_rows(
@@ -6171,22 +6259,27 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
results = db.archive_deleted_rows(max_rows=2, task_log=True)
expected = dict(task_log=2)
self._assertEqualObjects(expected, results[0])
- # Verify we have 2 left in main
- rows = self.conn.execute(qtl).fetchall()
- self.assertEqual(len(rows), 2)
- # Verify we have 4 in shadow
- rows = self.conn.execute(qstl).fetchall()
- self.assertEqual(len(rows), 4)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 2 left in main
+ rows = conn.execute(qtl).fetchall()
+ self.assertEqual(len(rows), 2)
+ # Verify we have 4 in shadow
+ rows = conn.execute(qstl).fetchall()
+ self.assertEqual(len(rows), 4)
+
# Archive the rest
results = db.archive_deleted_rows(max_rows=100, task_log=True)
expected = dict(task_log=2)
self._assertEqualObjects(expected, results[0])
- # Verify we have 0 left in main
- rows = self.conn.execute(qtl).fetchall()
- self.assertEqual(len(rows), 0)
- # Verify we have 6 in shadow
- rows = self.conn.execute(qstl).fetchall()
- self.assertEqual(len(rows), 6)
+
+ with self.engine.connect() as conn, conn.begin():
+ # Verify we have 0 left in main
+ rows = conn.execute(qtl).fetchall()
+ self.assertEqual(len(rows), 0)
+ # Verify we have 6 in shadow
+ rows = conn.execute(qstl).fetchall()
+ self.assertEqual(len(rows), 6)
class PciDeviceDBApiTestCase(test.TestCase, ModelsObjectComparatorMixin):
diff --git a/nova/tests/unit/objects/test_instance.py b/nova/tests/unit/objects/test_instance.py
index e187a4c251..6004bdf63d 100644
--- a/nova/tests/unit/objects/test_instance.py
+++ b/nova/tests/unit/objects/test_instance.py
@@ -2015,12 +2015,14 @@ class TestInstanceListObject(test_objects._LocalTest,
# manually here.
engine = db.get_engine()
table = sql_models.Instance.__table__
- with engine.connect() as conn:
- update = table.insert().values(user_id=self.context.user_id,
- project_id=self.context.project_id,
- uuid=uuids.nullinst,
- host='foo',
- hidden=None)
+ with engine.connect() as conn, conn.begin():
+ update = table.insert().values(
+ user_id=self.context.user_id,
+ project_id=self.context.project_id,
+ uuid=uuids.nullinst,
+ host='foo',
+ hidden=None,
+ )
conn.execute(update)
insts = objects.InstanceList.get_by_filters(self.context,