[test] get a chance to get proper garbage collection when running pytest on whole cw
--- a/devtools/repotest.py Wed Mar 03 17:59:05 2010 +0100
+++ b/devtools/repotest.py Wed Mar 03 18:30:25 2010 +0100
@@ -95,6 +95,31 @@
def __iter__(self):
return iter(sorted(self.origdict, key=self.sortkey))
+def schema_eids_idx(schema):
+ """return a dictionary mapping schema types to their eids so we can reread
+ it from the fs instead of the db (too costly) between tests
+ """
+ schema_eids = {}
+ for x in schema.entities():
+ schema_eids[x] = x.eid
+ for x in schema.relations():
+ schema_eids[x] = x.eid
+ for rdef in x.rdefs.itervalues():
+ schema_eids[(rdef.subject, rdef.rtype, rdef.object)] = rdef.eid
+ return schema_eids
+
+def restore_schema_eids_idx(schema, schema_eids):
+ """rebuild schema eid index"""
+ for x in schema.entities():
+ x.eid = schema_eids[x]
+ schema._eid_index[x.eid] = x
+ for x in schema.relations():
+ x.eid = schema_eids[x]
+ schema._eid_index[x.eid] = x
+ for rdef in x.rdefs.itervalues():
+ rdef.eid = schema_eids[(rdef.subject, rdef.rtype, rdef.object)]
+ schema._eid_index[rdef.eid] = rdef
+
from logilab.common.testlib import TestCase
from rql import RQLHelper
--- a/devtools/test/unittest_testlib.py Wed Mar 03 17:59:05 2010 +0100
+++ b/devtools/test/unittest_testlib.py Wed Mar 03 18:30:25 2010 +0100
@@ -15,6 +15,7 @@
from cubicweb.devtools import htmlparser
from cubicweb.devtools.testlib import CubicWebTC
+from cubicweb.pytestconf import clean_repo_test_cls
class WebTestTC(TestCase):
@@ -37,7 +38,7 @@
self.assertEquals(result.testsRun, 2)
self.assertEquals(len(result.errors), 0)
self.assertEquals(len(result.failures), 1)
-
+ clean_repo_test_cls(MyWebTest)
HTML_PAGE = u"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
--- a/hooks/test/unittest_syncschema.py Wed Mar 03 17:59:05 2010 +0100
+++ b/hooks/test/unittest_syncschema.py Wed Mar 03 18:30:25 2010 +0100
@@ -3,9 +3,11 @@
from cubicweb import ValidationError
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.server.sqlutils import SQL_PREFIX
-
+from cubicweb.devtools.repotest import schema_eids_idx, restore_schema_eids_idx
-SCHEMA_EIDS = {}
+def teardown_module(*args):
+ del SchemaModificationHooksTC.schema_eids
+
class SchemaModificationHooksTC(CubicWebTC):
reset_schema = True
@@ -15,29 +17,12 @@
# we have to read schema from the database to get eid for schema entities
config._cubes = None
cls.repo.fill_schema()
- # remember them so we can reread it from the fs instead of the db (too
- # costly) between tests
- for x in cls.repo.schema.entities():
- SCHEMA_EIDS[x] = x.eid
- for x in cls.repo.schema.relations():
- SCHEMA_EIDS[x] = x.eid
- for rdef in x.rdefs.itervalues():
- SCHEMA_EIDS[(rdef.subject, rdef.rtype, rdef.object)] = rdef.eid
+ cls.schema_eids = schema_eids_idx(cls.repo.schema)
@classmethod
def _refresh_repo(cls):
super(SchemaModificationHooksTC, cls)._refresh_repo()
- # rebuild schema eid index
- schema = cls.repo.schema
- for x in schema.entities():
- x.eid = SCHEMA_EIDS[x]
- schema._eid_index[x.eid] = x
- for x in cls.repo.schema.relations():
- x.eid = SCHEMA_EIDS[x]
- schema._eid_index[x.eid] = x
- for rdef in x.rdefs.itervalues():
- rdef.eid = SCHEMA_EIDS[(rdef.subject, rdef.rtype, rdef.object)]
- schema._eid_index[rdef.eid] = rdef
+ restore_schema_eids_idx(cls.repo.schema, cls.schema_eids)
def index_exists(self, etype, attr, unique=False):
self.session.set_pool()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pytestconf.py Wed Mar 03 18:30:25 2010 +0100
@@ -0,0 +1,29 @@
+"""pytest configuration file: we need this to properly remove ressources
+cached on test classes, at least until we've proper support for teardown_class
+"""
+import sys
+from os.path import split, splitext
+from logilab.common.pytest import PyTester
+
+from cubicweb.etwist.server import _gc_debug
+
+class CustomPyTester(PyTester):
+ def testfile(self, filename, batchmode=False):
+ try:
+ return super(CustomPyTester, self).testfile(filename, batchmode)
+ finally:
+ modname = splitext(split(filename)[1])[0]
+ for cls in vars(sys.modules[modname]).values():
+ if getattr(cls, '__module__', None) != modname:
+ continue
+ clean_repo_test_cls(cls)
+ #_gc_debug()
+
+def clean_repo_test_cls(cls):
+ if 'repo' in cls.__dict__:
+ if cls.repo.__dict__: # empty dict when already shutted down
+ cls.repo.shutdown()
+ del cls.repo
+ for clsattr in ('cnx', '_orig_cnx', 'config', '_config', 'vreg', 'schema'):
+ if clsattr in cls.__dict__:
+ delattr(cls, clsattr)
--- a/server/__init__.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/__init__.py Wed Mar 03 18:30:25 2010 +0100
@@ -200,6 +200,7 @@
cnx.commit()
cnx.close()
session.close()
+ repo.shutdown()
# restore initial configuration
config.creating = False
config.read_instance_schema = read_instance_schema
--- a/server/test/unittest_checkintegrity.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_checkintegrity.py Wed Mar 03 18:30:25 2010 +0100
@@ -13,10 +13,9 @@
from cubicweb.server.checkintegrity import check
-repo, cnx = init_test_database()
-
class CheckIntegrityTC(TestCase):
def test(self):
+ repo, cnx = init_test_database()
sys.stderr = sys.stdout = StringIO()
try:
check(repo, cnx, ('entities', 'relations', 'text_index', 'metadata'),
@@ -24,6 +23,7 @@
finally:
sys.stderr = sys.__stderr__
sys.stdout = sys.__stdout__
+ repo.shutdown()
if __name__ == '__main__':
unittest_main()
--- a/server/test/unittest_hook.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_hook.py Wed Mar 03 18:30:25 2010 +0100
@@ -69,6 +69,10 @@
config.bootstrap_cubes()
schema = config.load_schema()
+def teardown_module(*args):
+ global config, schema
+ del config, schema
+
class AddAnyHook(hook.Hook):
__regid__ = 'addany'
category = 'cat1'
--- a/server/test/unittest_ldapuser.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_ldapuser.py Wed Mar 03 18:30:25 2010 +0100
@@ -370,6 +370,11 @@
LDAPUserSourceTC._init_repo()
repo = LDAPUserSourceTC.repo
+def teardown_module(*args):
+ global repo
+ del repo
+ del RQL2LDAPFilterTC.schema
+
class RQL2LDAPFilterTC(RQLGeneratorTC):
schema = repo.schema
--- a/server/test/unittest_msplanner.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_msplanner.py Wed Mar 03 18:30:25 2010 +0100
@@ -60,6 +60,11 @@
# keep cnx so it's not garbage collected and the associated session is closed
repo, cnx = init_test_database()
+def teardown_module(*args):
+ global repo, cnx
+ del repo, cnx
+
+
class BaseMSPlannerTC(BasePlannerTC):
"""test planner related feature on a 3-sources repository:
--- a/server/test/unittest_multisources.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_multisources.py Wed Mar 03 18:30:25 2010 +0100
@@ -48,7 +48,12 @@
def teardown_module(*args):
PyroRQLSource.get_connection = PyroRQLSource_get_connection
Connection.close = Connection_close
-
+ global repo2, cnx2, repo3, cnx3
+ repo2.shutdown()
+ repo3.shutdown()
+ del repo2, cnx2, repo3, cnx3
+ #del TwoSourcesTC.config.vreg
+ #del TwoSourcesTC.config
class TwoSourcesTC(CubicWebTC):
config = TwoSourcesConfiguration('data')
@@ -130,7 +135,7 @@
cu = cnx.cursor()
rset = cu.execute('Any X WHERE X has_text "card"')
self.assertEquals(len(rset), 5, zip(rset.rows, rset.description))
- cnx.close()
+ Connection_close(cnx)
def test_synchronization(self):
cu = cnx2.cursor()
--- a/server/test/unittest_querier.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_querier.py Wed Mar 03 18:30:25 2010 +0100
@@ -48,6 +48,11 @@
repo, cnx = init_test_database()
+def teardown_module(*args):
+ global repo, cnx
+ cnx.close()
+ repo.shutdown()
+ del repo, cnx
class UtilsTC(BaseQuerierTC):
--- a/server/test/unittest_repository.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_repository.py Wed Mar 03 18:30:25 2010 +0100
@@ -21,7 +21,7 @@
from cubicweb import (BadConnectionId, RepositoryError, ValidationError,
UnknownEid, AuthenticationError)
from cubicweb.schema import CubicWebSchema, RQLConstraint
-from cubicweb.dbapi import connect, repo_connect, multiple_connections_unfix
+from cubicweb.dbapi import connect, multiple_connections_unfix
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.devtools.repotest import tuplify
from cubicweb.server import repository, hook
@@ -38,25 +38,29 @@
"""
def test_fill_schema(self):
- self.repo.schema = CubicWebSchema(self.repo.config.appid)
- self.repo.config._cubes = None # avoid assertion error
- self.repo.config.repairing = True # avoid versions checking
- self.repo.fill_schema()
- table = SQL_PREFIX + 'CWEType'
- namecol = SQL_PREFIX + 'name'
- finalcol = SQL_PREFIX + 'final'
- self.session.set_pool()
- cu = self.session.system_sql('SELECT %s FROM %s WHERE %s is NULL' % (
- namecol, table, finalcol))
- self.assertEquals(cu.fetchall(), [])
- cu = self.session.system_sql('SELECT %s FROM %s WHERE %s=%%(final)s ORDER BY %s'
- % (namecol, table, finalcol, namecol), {'final': 'TRUE'})
- self.assertEquals(cu.fetchall(), [(u'Boolean',), (u'Bytes',),
- (u'Date',), (u'Datetime',),
- (u'Decimal',),(u'Float',),
- (u'Int',),
- (u'Interval',), (u'Password',),
- (u'String',), (u'Time',)])
+ origshema = self.repo.schema
+ try:
+ self.repo.schema = CubicWebSchema(self.repo.config.appid)
+ self.repo.config._cubes = None # avoid assertion error
+ self.repo.config.repairing = True # avoid versions checking
+ self.repo.fill_schema()
+ table = SQL_PREFIX + 'CWEType'
+ namecol = SQL_PREFIX + 'name'
+ finalcol = SQL_PREFIX + 'final'
+ self.session.set_pool()
+ cu = self.session.system_sql('SELECT %s FROM %s WHERE %s is NULL' % (
+ namecol, table, finalcol))
+ self.assertEquals(cu.fetchall(), [])
+ cu = self.session.system_sql('SELECT %s FROM %s WHERE %s=%%(final)s ORDER BY %s'
+ % (namecol, table, finalcol, namecol), {'final': 'TRUE'})
+ self.assertEquals(cu.fetchall(), [(u'Boolean',), (u'Bytes',),
+ (u'Date',), (u'Datetime',),
+ (u'Decimal',),(u'Float',),
+ (u'Int',),
+ (u'Interval',), (u'Password',),
+ (u'String',), (u'Time',)])
+ finally:
+ self.repo.set_schema(origshema)
def test_schema_has_owner(self):
repo = self.repo
@@ -263,6 +267,8 @@
self.fail('something went wrong, thread still alive')
finally:
repository.pyro_unregister(self.repo.config)
+ from logilab.common import pyro_ext
+ pyro_ext._DAEMONS.clear()
def _pyro_client(self, done):
cnx = connect(self.repo.config.appid, u'admin', password='gingkow')
@@ -456,13 +462,6 @@
u'system.version.tag'])
CALLED = []
-class EcritParHook(hook.Hook):
- __regid__ = 'inlinedrelhook'
- __select__ = hook.Hook.__select__ & hook.match_rtype('ecrit_par')
- events = ('before_add_relation', 'after_add_relation',
- 'before_delete_relation', 'after_delete_relation')
- def __call__(self):
- CALLED.append((self.event, self.eidfrom, self.rtype, self.eidto))
class InlineRelHooksTC(CubicWebTC):
"""test relation hooks are called for inlined relations
@@ -477,6 +476,14 @@
def test_inline_relation(self):
"""make sure <event>_relation hooks are called for inlined relation"""
+ class EcritParHook(hook.Hook):
+ __regid__ = 'inlinedrelhook'
+ __select__ = hook.Hook.__select__ & hook.match_rtype('ecrit_par')
+ events = ('before_add_relation', 'after_add_relation',
+ 'before_delete_relation', 'after_delete_relation')
+ def __call__(self):
+ CALLED.append((self.event, self.eidfrom, self.rtype, self.eidto))
+
self.hm.register(EcritParHook)
eidp = self.execute('INSERT Personne X: X nom "toto"')[0][0]
eidn = self.execute('INSERT Note X: X type "T"')[0][0]
--- a/server/test/unittest_rql2sql.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_rql2sql.py Wed Mar 03 18:30:25 2010 +0100
@@ -37,6 +37,10 @@
schema['state_of'].inlined = False
schema['comments'].inlined = False
+def teardown_module(*args):
+ global config, schema
+ del config, schema
+
PARSER = [
(r"Personne P WHERE P nom 'Zig\'oto';",
'''SELECT _P.cw_eid
--- a/server/test/unittest_rqlannotation.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_rqlannotation.py Wed Mar 03 18:30:25 2010 +0100
@@ -8,6 +8,11 @@
repo, cnx = init_test_database()
+def teardown_module(*args):
+ global repo, cnx
+ del repo, cnx
+
+
class SQLGenAnnotatorTC(BaseQuerierTC):
repo = repo
--- a/server/test/unittest_schemaserial.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_schemaserial.py Wed Mar 03 18:30:25 2010 +0100
@@ -15,6 +15,10 @@
config.bootstrap_cubes()
schema = loader.load(config)
+def teardown_module(*args):
+ global schema, config, loader
+ del schema, config, loader
+
from cubicweb.server.schemaserial import *
from cubicweb.server.schemaserial import _erperms2rql as erperms2rql
--- a/server/test/unittest_ssplanner.py Wed Mar 03 17:59:05 2010 +0100
+++ b/server/test/unittest_ssplanner.py Wed Mar 03 18:30:25 2010 +0100
@@ -12,6 +12,10 @@
# keep cnx so it's not garbage collected and the associated session closed
repo, cnx = init_test_database()
+def teardown_module(*args):
+ global repo, cnx
+ del repo, cnx
+
class SSPlannerTC(BasePlannerTC):
repo = repo
_test = test_plan