[devtools] set .config in setUpClass instead of using a cache in a classproperty
This is much clearer and avoid problem with py.test introspection that triggered
creation and caching of the configuration before actual test execution. This
caused pb in unittest_postgres.PostgresStatementTimeoutTC where configuration
was built before module's setup, hence source configuration was missing
information about where to find the pg cluster.
--- a/cubicweb/devtools/testlib.py Fri May 20 12:01:42 2016 +0200
+++ b/cubicweb/devtools/testlib.py Fri May 20 17:05:39 2016 +0200
@@ -313,6 +313,15 @@
# anonymous is logged by default in cubicweb test cases
anonymous_allowed = True
+ @classmethod
+ def setUpClass(cls):
+ test_module_file = sys.modules[cls.__module__].__file__
+ assert 'config' not in cls.__dict__, (
+ '%s has a config class attribute before entering setUpClass. '
+ 'Let CubicWebTC.setUpClass instantiate it and modify it afterwards.' % cls)
+ cls.config = cls.configcls(cls.appid, test_module_file)
+ cls.config.mode = 'test'
+
def __init__(self, *args, **kwargs):
self._admin_session = None
self.repo = None
@@ -365,24 +374,6 @@
# config management ########################################################
- @classproperty
- def config(cls):
- """return the configuration object
-
- Configuration is cached on the test class.
- """
- if cls is CubicWebTC:
- # Prevent direct use of CubicWebTC directly to avoid database
- # caching issues
- return None
- try:
- return cls.__dict__['_config']
- except KeyError:
- test_module_file = sys.modules[cls.__module__].__file__
- config = cls._config = cls.configcls(cls.appid, test_module_file)
- config.mode = 'test'
- return config
-
@classmethod # XXX could be turned into a regular method
def init_config(cls, config):
"""configuration initialization hooks.
@@ -441,6 +432,9 @@
# default test setup and teardown #########################################
def setUp(self):
+ assert hasattr(self, 'config'), (
+ 'It seems that CubicWebTC.setUpClass has not been called. '
+ 'Missing super() call in %s?' % self.setUpClass)
# monkey patch send mail operation so emails are sent synchronously
self._patch_SendMailOp()
previous_failure = self.__class__.__dict__.get('_repo_init_failed')
--- a/cubicweb/server/test/unittest_ldapsource.py Fri May 20 12:01:42 2016 +0200
+++ b/cubicweb/server/test/unittest_ldapsource.py Fri May 20 17:05:39 2016 +0200
@@ -108,6 +108,10 @@
sys.stdout.write(stdout)
sys.stderr.write(stderr)
config.info('DONE')
+ try:
+ shutil.rmtree(cls._tmpdir)
+ except:
+ pass
class LDAPFeedTestBase(CubicWebTC):
@@ -116,6 +120,15 @@
@classmethod
def setUpClass(cls):
+ super(LDAPFeedTestBase, cls).setUpClass()
+ cls.init_slapd()
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.terminate_slapd()
+
+ @classmethod
+ def init_slapd(cls):
for path in ('/usr/sbin/slapd',
'/usr/sbin/slapadd',
'/usr/bin/ldapmodify'):
@@ -126,12 +139,8 @@
cls._tmpdir = create_slapd_configuration(cls)
@classmethod
- def tearDownClass(cls):
+ def terminate_slapd(cls):
terminate_slapd(cls)
- try:
- shutil.rmtree(cls._tmpdir)
- except:
- pass
@classmethod
def pre_setup_database(cls, cnx, config):
@@ -461,8 +470,8 @@
finally:
# back to normal ldap setup
- self.tearDownClass()
- self.setUpClass()
+ self.terminate_slapd()
+ self.init_slapd()
def test_group_member_deleted(self):
with self.repo.internal_cnx() as cnx:
@@ -485,8 +494,8 @@
self.assertEqual(len(rset), 0, rset.rows)
finally:
# back to normal ldap setup
- self.tearDownClass()
- self.setUpClass()
+ self.terminate_slapd()
+ self.init_slapd()
if __name__ == '__main__':
--- a/cubicweb/server/test/unittest_postgres.py Fri May 20 12:01:42 2016 +0200
+++ b/cubicweb/server/test/unittest_postgres.py Fri May 20 17:05:39 2016 +0200
@@ -153,6 +153,7 @@
@classmethod
def setUpClass(cls):
+ super(PostgresStatementTimeoutTC, cls).setUpClass()
cls.orig_connect_hooks = lgdb.SQL_CONNECT_HOOKS['postgres'][:]
@classmethod
--- a/cubicweb/web/test/unittest_application.py Fri May 20 12:01:42 2016 +0200
+++ b/cubicweb/web/test/unittest_application.py Fri May 20 17:05:39 2016 +0200
@@ -146,14 +146,10 @@
class ApplicationTC(CubicWebTC):
- @classproperty
- def config(cls):
- try:
- return cls.__dict__['_config']
- except KeyError:
- config = super(ApplicationTC, cls).config
- config.global_set_option('allow-email-login', True)
- return config
+ @classmethod
+ def setUpClass(cls):
+ super(ApplicationTC, cls).setUpClass()
+ cls.config.global_set_option('allow-email-login', True)
def test_cnx_user_groups_sync(self):
with self.admin_access.client_cnx() as cnx: