From f318f822fcf6dec4c3cd9b7e5111f3e1371aa51a Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Wed, 27 Oct 2021 13:26:18 +0200 Subject: [PATCH] Remove SESSION_CONFIGURED global from DB fixture The SESSION_CONFIGURED global flag is used in the Database fixture to guard against the reconfiguration of the DB context in each test as the global transaction factory does not allow such reconfiguration. However this global is error prone for multiple reasons: * there are tests that actually configure the factory outside of the fixture causing tests to interfere * we use one single global flag but we always have two separate Database fixture one for the api DB and one for the main DB. Still the fixture instantiated first will do the configuration of both DB factory. This patch replaces the global with two individual oslo_db enginefacade patch_factory() calls that allows patching and resetting the global factory per test case. Change-Id: Ifc070d19a18a2d66f1a7bd5898428b12901dfe9e --- nova/tests/fixtures/nova.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/nova/tests/fixtures/nova.py b/nova/tests/fixtures/nova.py index 9169c0692c..e180c80f98 100644 --- a/nova/tests/fixtures/nova.py +++ b/nova/tests/fixtures/nova.py @@ -31,6 +31,7 @@ from openstack import service_description from oslo_concurrency import lockutils from oslo_config import cfg from oslo_db import exception as db_exc +from oslo_db.sqlalchemy import enginefacade from oslo_log import log as logging import oslo_messaging as messaging from oslo_messaging import conffixture as messaging_conffixture @@ -64,7 +65,6 @@ CONF = cfg.CONF LOG = logging.getLogger(__name__) DB_SCHEMA = collections.defaultdict(str) -SESSION_CONFIGURED = False PROJECT_ID = '6f70656e737461636b20342065766572' @@ -611,20 +611,21 @@ class Database(fixtures.Fixture): """ super().__init__() - # NOTE(pkholkin): oslo_db.enginefacade is configured in tests the - # same way as it is done for any other service that uses DB - global SESSION_CONFIGURED - if not SESSION_CONFIGURED: - main_db_api.configure(CONF) - api_db_api.configure(CONF) - SESSION_CONFIGURED = True - assert database in {'main', 'api'}, f'Unrecognized database {database}' self.database = database self.version = version if database == 'main': + # NOTE(gibi): this inject a new factory for each test and + # self.factory_reset is used to clean up the factory at the end + # of the test case. This way we can let each test configure the + # factory so we can avoid having a global flag guarding against + # factory re-configuration + self.factory_reset = main_db_api.context_manager.patch_factory( + enginefacade._TransactionFactory()) + main_db_api.configure(CONF) + if connection is not None: ctxt_mgr = main_db_api.create_context_manager( connection=connection) @@ -634,6 +635,12 @@ class Database(fixtures.Fixture): elif database == 'api': assert connection is None, 'Not supported for the API database' + # NOTE(gibi): similar note applies here as for the main_db_api + # above + self.factory_reset = api_db_api.context_manager.patch_factory( + enginefacade._TransactionFactory()) + api_db_api.configure(CONF) + self.get_engine = api_db_api.get_engine def setUp(self): @@ -656,6 +663,7 @@ class Database(fixtures.Fixture): engine.dispose() def reset(self): + self.factory_reset() engine = self.get_engine() engine.dispose() self._cache_schema()