# HG changeset patch # User Sylvain Thénault # Date 1267637425 -3600 # Node ID 162b2b127b15bba3e8bbe0b7b59b1c74de2d29f5 # Parent ec9c20c6b9f7d5fca3875e04742a0680e845ae96 [test] get a chance to get proper garbage collection when running pytest on whole cw diff -r ec9c20c6b9f7 -r 162b2b127b15 devtools/repotest.py --- 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 diff -r ec9c20c6b9f7 -r 162b2b127b15 devtools/test/unittest_testlib.py --- 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""" diff -r ec9c20c6b9f7 -r 162b2b127b15 hooks/test/unittest_syncschema.py --- 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() diff -r ec9c20c6b9f7 -r 162b2b127b15 pytestconf.py --- /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) diff -r ec9c20c6b9f7 -r 162b2b127b15 server/__init__.py --- 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 diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_checkintegrity.py --- 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() diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_hook.py --- 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' diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_ldapuser.py --- 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 diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_msplanner.py --- 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: diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_multisources.py --- 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() diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_querier.py --- 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): diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_repository.py --- 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 _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] diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_rql2sql.py --- 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 diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_rqlannotation.py --- 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 diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_schemaserial.py --- 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 diff -r ec9c20c6b9f7 -r 162b2b127b15 server/test/unittest_ssplanner.py --- 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