devtools/__init__.py
branchstable
changeset 7214 70538ea2532d
parent 7129 455b503fb7ff
child 7217 4b860903d8c7
equal deleted inserted replaced
7213:7644e68c4e9f 7214:70538ea2532d
   230         # threads
   230         # threads
   231         return True
   231         return True
   232 
   232 
   233 # XXX merge with BaseApptestConfiguration ?
   233 # XXX merge with BaseApptestConfiguration ?
   234 class ApptestConfiguration(BaseApptestConfiguration):
   234 class ApptestConfiguration(BaseApptestConfiguration):
       
   235     # `skip_db_create_and_restore` controls wether or not the test database
       
   236     # should be created / backuped / restored. If set to True, those
       
   237     # steps are completely skipped, the database is used as is and is
       
   238     # considered initialized
       
   239     skip_db_create_and_restore = False
   235 
   240 
   236     def __init__(self, appid, apphome=None,
   241     def __init__(self, appid, apphome=None,
   237                  log_threshold=logging.CRITICAL, sourcefile=None):
   242                  log_threshold=logging.CRITICAL, sourcefile=None):
   238         BaseApptestConfiguration.__init__(self, appid, apphome,
   243         BaseApptestConfiguration.__init__(self, appid, apphome,
   239                                           log_threshold=log_threshold)
   244                                           log_threshold=log_threshold)
   258           def test_something(self):
   263           def test_something(self):
   259               rset = self.execute('Any X WHERE X is CWUser')
   264               rset = self.execute('Any X WHERE X is CWUser')
   260               self.view('foaf', rset)
   265               self.view('foaf', rset)
   261 
   266 
   262     """
   267     """
       
   268     skip_db_create_and_restore = True
   263     read_instance_schema = True # read schema from database
   269     read_instance_schema = True # read schema from database
   264 
   270 
   265 
   271 
   266 # test database handling #######################################################
   272 # test database handling #######################################################
   267 
   273 
   475             pre_setup_func(session, self.config)
   481             pre_setup_func(session, self.config)
   476             session.commit()
   482             session.commit()
   477             cnx.close()
   483             cnx.close()
   478         self.backup_database(test_db_id)
   484         self.backup_database(test_db_id)
   479 
   485 
       
   486 
       
   487 class NoCreateDropDatabaseHandler(TestDataBaseHandler):
       
   488     """This handler is used if config.skip_db_create_and_restore is True
       
   489 
       
   490     This is typically the case with RealDBConfig. In that case,
       
   491     we explicitely want to skip init / backup / restore phases.
       
   492 
       
   493     This handler redefines the three corresponding methods and delegates
       
   494     to original handler for any other method / attribute
       
   495     """
       
   496 
       
   497     def __init__(self, base_handler):
       
   498         self.base_handler = base_handler
       
   499 
       
   500     # override init / backup / restore methods
       
   501     def init_test_database(self):
       
   502         pass
       
   503 
       
   504     def backup_database(self, db_id):
       
   505         pass
       
   506 
       
   507     def restore_database(self, db_id):
       
   508         pass
       
   509 
       
   510     # delegate to original handler in all other cases
       
   511     def __getattr__(self, attrname):
       
   512         return getattr(self.base_handler, attrname)
       
   513 
       
   514 
   480 ### postgres test database handling ############################################
   515 ### postgres test database handling ############################################
   481 
   516 
   482 class PostgresTestDataBaseHandler(TestDataBaseHandler):
   517 class PostgresTestDataBaseHandler(TestDataBaseHandler):
   483 
       
   484     # XXX
       
   485     # XXX PostgresTestDataBaseHandler Have not been tested at all.
       
   486     # XXX
       
   487     DRIVER = 'postgres'
   518     DRIVER = 'postgres'
   488 
   519 
   489     @property
   520     @property
   490     @cached
   521     @cached
   491     def helper(self):
   522     def helper(self):
   502     @property
   533     @property
   503     @cached
   534     @cached
   504     def cursor(self):
   535     def cursor(self):
   505         return self.dbcnx.cursor()
   536         return self.dbcnx.cursor()
   506 
   537 
       
   538     def process_cache_entry(self, directory, dbname, db_id, entry):
       
   539         backup_name = self._backup_name(db_id)
       
   540         if backup_name in self.helper.list_databases(self.cursor):
       
   541             return backup_name
       
   542         return None
       
   543 
   507     def init_test_database(self):
   544     def init_test_database(self):
   508         """initialize a fresh postgresql databse used for testing purpose"""
   545         """initialize a fresh postgresql database used for testing purpose"""
   509         from cubicweb.server import init_repository
   546         from cubicweb.server import init_repository
   510         from cubicweb.server.serverctl import system_source_cnx, createdb
   547         from cubicweb.server.serverctl import system_source_cnx, createdb
   511         # connect on the dbms system base to create our base
   548         # connect on the dbms system base to create our base
   512         try:
   549         try:
   513             self._drop(self.dbname)
   550             self._drop(self.dbname)
   514 
       
   515             createdb(self.helper, self.system_source, self.dbcnx, self.cursor)
   551             createdb(self.helper, self.system_source, self.dbcnx, self.cursor)
   516             self.dbcnx.commit()
   552             self.dbcnx.commit()
   517             cnx = system_source_cnx(self.system_source, special_privs='LANGUAGE C',
   553             cnx = system_source_cnx(self.system_source, special_privs='LANGUAGE C',
   518                                     interactive=False)
   554                                     interactive=False)
   519             templcursor = cnx.cursor()
   555             templcursor = cnx.cursor()
   553         backup_name = '_'.join(('cache', self._config_id, self.dbname, db_id))
   589         backup_name = '_'.join(('cache', self._config_id, self.dbname, db_id))
   554         return backup_name.lower()
   590         return backup_name.lower()
   555 
   591 
   556     def _drop(self, db_name):
   592     def _drop(self, db_name):
   557         if db_name in self.helper.list_databases(self.cursor):
   593         if db_name in self.helper.list_databases(self.cursor):
   558             #print 'dropping overwritted database:', db_name
       
   559             self.cursor.execute('DROP DATABASE %s' % db_name)
   594             self.cursor.execute('DROP DATABASE %s' % db_name)
   560             self.dbcnx.commit()
   595             self.dbcnx.commit()
   561 
   596 
   562     def _backup_database(self, db_id):
   597     def _backup_database(self, db_id):
   563         """Actual backup the current database.
   598         """Actual backup the current database.
   565         return a value to be stored in db_cache to allow restoration"""
   600         return a value to be stored in db_cache to allow restoration"""
   566         from cubicweb.server.serverctl import createdb
   601         from cubicweb.server.serverctl import createdb
   567         orig_name = self.system_source['db-name']
   602         orig_name = self.system_source['db-name']
   568         try:
   603         try:
   569             backup_name = self._backup_name(db_id)
   604             backup_name = self._backup_name(db_id)
   570             #print 'storing postgres backup as', backup_name
       
   571             self._drop(backup_name)
   605             self._drop(backup_name)
   572             self.system_source['db-name'] = backup_name
   606             self.system_source['db-name'] = backup_name
   573             createdb(self.helper, self.system_source, self.dbcnx, self.cursor, template=orig_name)
   607             createdb(self.helper, self.system_source, self.dbcnx, self.cursor, template=orig_name)
   574             self.dbcnx.commit()
   608             self.dbcnx.commit()
   575             return backup_name
   609             return backup_name
   579     def _restore_database(self, backup_coordinates, config):
   613     def _restore_database(self, backup_coordinates, config):
   580         from cubicweb.server.serverctl import createdb
   614         from cubicweb.server.serverctl import createdb
   581         """Actual restore of the current database.
   615         """Actual restore of the current database.
   582 
   616 
   583         Use the value tostored in db_cache as input """
   617         Use the value tostored in db_cache as input """
   584         #print 'restoring postgrest backup from', backup_coordinates
       
   585         self._drop(self.dbname)
   618         self._drop(self.dbname)
   586         createdb(self.helper, self.system_source, self.dbcnx, self.cursor,
   619         createdb(self.helper, self.system_source, self.dbcnx, self.cursor,
   587                  template=backup_coordinates)
   620                  template=backup_coordinates)
   588         self.dbcnx.commit()
   621         self.dbcnx.commit()
   589 
   622 
   645 
   678 
   646     def _restore_database(self, backup_coordinates, _config):
   679     def _restore_database(self, backup_coordinates, _config):
   647         # remove database file if it exists ?
   680         # remove database file if it exists ?
   648         dbfile = self.absolute_dbfile()
   681         dbfile = self.absolute_dbfile()
   649         self._cleanup_database(dbfile)
   682         self._cleanup_database(dbfile)
   650         #print 'resto from', backup_coordinates
       
   651         shutil.copy(backup_coordinates, dbfile)
   683         shutil.copy(backup_coordinates, dbfile)
   652         repo = self.get_repo()
   684         repo = self.get_repo()
   653 
   685 
   654     def init_test_database(self):
   686     def init_test_database(self):
   655         """initialize a fresh sqlite databse used for testing purpose"""
   687         """initialize a fresh sqlite databse used for testing purpose"""
   752     driver = sources['system']['db-driver']
   784     driver = sources['system']['db-driver']
   753     key = (driver, config)
   785     key = (driver, config)
   754     handlerkls = HANDLERS.get(driver, None)
   786     handlerkls = HANDLERS.get(driver, None)
   755     if handlerkls is not None:
   787     if handlerkls is not None:
   756         handler = handlerkls(config)
   788         handler = handlerkls(config)
       
   789         if config.skip_db_create_and_restore:
       
   790             handler = NoCreateDropDatabaseHandler(handler)
   757         HCACHE.set(config, handler)
   791         HCACHE.set(config, handler)
   758         return handler
   792         return handler
   759     else:
   793     else:
   760         raise ValueError('no initialization function for driver %r' % driver)
   794         raise ValueError('no initialization function for driver %r' % driver)
   761 
   795