summaryrefslogtreecommitdiff
path: root/nova/tests/unit/db/api
diff options
context:
space:
mode:
authorBalazs Gibizer <balazs.gibizer@est.tech>2021-10-27 16:29:29 +0200
committerBalazs Gibizer <balazs.gibizer@est.tech>2021-11-05 11:41:27 +0100
commita7bccff06b871765fb87ee3e9edd9458c7f73701 (patch)
tree4b515ad831574742e2130282ae42a1bcf3745558 /nova/tests/unit/db/api
parent063ed41174c27c20871696f7c6dcb1eddb4310ee (diff)
downloadnova-a7bccff06b871765fb87ee3e9edd9458c7f73701.tar.gz
Fix interference in db unit test
We discovered that two unit test cases added in I0647bb8545c1464b521a1d866cf5ee674aea2eae cause errors like oslo_db.sqlalchemy.enginefacade.AlreadyStartedError: this TransactionFactory is already started when the db tests run selectively with tox -e py38 nova.tests.unit.db but does not cause errors if the whole unit test suit is run. This error happened because our db code uses two global transaction factory, one for the api DB and one for the main DB. There was a global flag SESSION_CONFIGURED in our Database fixture that guarded against double initialization of the factory. But the faulty test cases in question do not use our Database fixture but use the OpportunisticDBTestMixin from oslo_db. Obviously that fixture does not know about our SESSION_CONFIGURED global. So if one of the offending test case ran first in an executor then that initialized the transaction factory globally and a later test that uses our Database fixture tried to configure it again leading to the error. For some unknown reason if these tests were run in the opposite order the faulty re-initialization did not happen. Probably the OpportunisticDBTestMixin was able to prevent that. A previous patch already removed the global SESSION_CONFIGURED flag from our fixture and replaced it with a per DB specific patch_factory calls that allow resetting the state of the factory at the end of each test case. This would already solve the current test case issue as only our offending test cases would initialize the global factory without cleanup and we have one test case per DB. So there would be no interference. However if in the future we add similar test cases then those can still interfere through the global factory. So this patch fixes the two offending test case. Also it extends the DatabasePoisonFixture used for the NoDbTestCase tesst. The poison now detects if the test case starts any transaction factory. This poison caught another offender test case, test_db_sync_with_special_symbols_in_connection_string, that was marked NoDb but actually using the database. It is now changed to declare itself as a test that sets up the DB manually and also it is changed to use the Database fixture instead of touching the global factory directly. Closes-Bug: #1948963 Change-Id: Id96f1795034490c13125ebbab49b029fb96af1c7
Diffstat (limited to 'nova/tests/unit/db/api')
-rw-r--r--nova/tests/unit/db/api/test_migrations.py11
1 files changed, 7 insertions, 4 deletions
diff --git a/nova/tests/unit/db/api/test_migrations.py b/nova/tests/unit/db/api/test_migrations.py
index 10c0c8feb9..1b14d569db 100644
--- a/nova/tests/unit/db/api/test_migrations.py
+++ b/nova/tests/unit/db/api/test_migrations.py
@@ -275,11 +275,14 @@ class NovaMigrationsWalk(
self._migrate_up(connection, revision)
def test_db_version_alembic(self):
- migration.db_sync(database='api')
+ engine = enginefacade.writer.get_engine()
- script = alembic_script.ScriptDirectory.from_config(self.config)
- head = script.get_current_head()
- self.assertEqual(head, migration.db_version(database='api'))
+ with mock.patch.object(migration, '_get_engine', return_value=engine):
+ migration.db_sync(database='api')
+
+ script = alembic_script.ScriptDirectory.from_config(self.config)
+ head = script.get_current_head()
+ self.assertEqual(head, migration.db_version(database='api'))
class TestMigrationsWalkSQLite(