source: indico/indico/tests/core.py @ 011a92

hello-world-walkthroughipv6v0.98-seriesv0.98.2v0.98.3v0.99v1.0v1.1
Last change on this file since 011a92 was 011a92, checked in by Pedro Ferreira <jose.pedro.ferreira@…>, 16 months ago

[FIX] Functional tests - redirect loop

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[28b84b]1# -*- coding: utf-8 -*-
2##
3## This file is part of CDS Indico.
4## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
5##
6## CDS Indico is free software; you can redistribute it and/or
7## modify it under the terms of the GNU General Public License as
8## published by the Free Software Foundation; either version 2 of the
9## License, or (at your option) any later version.
10##
11## CDS Indico is distributed in the hope that it will be useful, but
12## WITHOUT ANY WARRANTY; without even the implied warranty of
13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14## General Public License for more details.
15##
16## You should have received a copy of the GNU General Public License
17## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
18## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19
[5e89ba]20# pylint: disable-msg=W0401
21
22"""
23This is the very core of indico.tests
24Here is defined the TestManager class, that provides a single point of access
25to the outside world.
26"""
[28b84b]27
28# System modules
[cc5d1b]29import os, sys, shutil, signal, commands, tempfile, pkg_resources
[28b84b]30
31# Database
32import transaction
33from MaKaC.common.db import DBMgr
34
35# Indico
[cc5d1b]36import indico
[b7b4b1]37from indico.util.console import colored
[58c67a]38from indico.tests.config import TestConfig
[2da75d]39from indico.tests.base import TestOptionException, FakeMailThread
[28b84b]40from indico.tests.runners import *
41
[cc5d1b]42# Indico legacy
43from MaKaC.common.Configuration import Config
44
[58c67a]45TEST_RUNNERS = {'unit': UnitTestRunner,
46                'functional': FunctionalTestRunner,
47                'pylint': PylintTestRunner,
48                'jsunit': JSUnitTestRunner,
49                'jslint': JSLintTestRunner,
50                'grid': GridTestRunner}
51
[28b84b]52
53class TestManager(object):
54    """
55    Main class, the heart of the test API.
56    Launches all the tests according to the parameters that are passed
57    """
58
59    __instance = None
60
61    def __init__(self):
[5e89ba]62        """
63        Initializes the object
64        """
[28b84b]65        self.dbmgr = None
66        self.zeoServer = None
[58c67a]67        self.tempDirs = {}
68        self.dbFolder = None
[28b84b]69
[49bc7c]70    @staticmethod
[574b7d]71    def _title(text):
72        """
73        Prints an title
74        """
75        print colored("-- " + str(text), 'yellow', attrs=['bold'])
76
77    @staticmethod
[49bc7c]78    def _info(message):
79        """
80        Prints an info message
81        """
82        print colored("-- " + str(message), 'cyan')
83
84    @staticmethod
[574b7d]85    def _error(message):
86        """
87        Prints an info message
88        """
89        print colored("-- " + str(message), 'red')
90
91    @staticmethod
[49bc7c]92    def _debug(message):
93        """
94        Prints an info message
95        """
96        print colored("-- " + str(message), 'grey')
97
[2da75d]98    def main(self, testsToRun, options):
[5e89ba]99        """
100        Runs the main test cycle, iterating over all the TestRunners available
101
102         * testsToRun - a list of strings specifying which tests to run
103         * options - test options (such as verbosity...)
104        """
[574b7d]105        result = False
[59779c]106        killself = options.pop('killself', False)
[28b84b]107
[574b7d]108        TestManager._title("Starting test framework\n")
[28b84b]109
[2da75d]110        self._setFakeConfig()
111        self._startSMTPServer()
112        self._startManageDB()
[28b84b]113
[2da75d]114        try:
115            for test in testsToRun:
116                if test in TEST_RUNNERS:
117                    try:
118                        result = TEST_RUNNERS[test](**options).run()
119                    except TestOptionException, e:
120                        TestManager._error(e)
121                else:
122                    print colored("[ERR] Test set '%s' does not exist. "
123                                  "It has to be added in the TEST_RUNNERS variable\n",
124                                  'red') % test
125        finally:
126            # whatever happens, clean this mess up
[59779c]127            self._stopManageDB(killself)
[2da75d]128            self._stopSMTPServer()
[28b84b]129
[59779c]130        if killself:
131            # Forcefully kill ourselves. This avoids waiting for the db to shutdown (SLOW)
132            self._info('Committing suicide to avoid waiting for slow database shutdown')
133            os.kill(os.getpid(), 9)
134
[574b7d]135        if result:
136            return 0
137        else:
138            return -1
[28b84b]139
[2da75d]140    def _setFakeConfig(self):
[cc5d1b]141        """
142        Sets a fake configuration for the current process, using a temporary directory
143        """
[2da75d]144        config = Config.getInstance()
[5e89ba]145
[2da75d]146        temp = tempfile.mkdtemp(prefix="indico_")
147        self._info('Using %s as temporary dir' % temp)
[28b84b]148
[cc5d1b]149        os.mkdir(os.path.join(temp, 'log'))
150        os.mkdir(os.path.join(temp, 'archive'))
151
152        indicoDist = pkg_resources.get_distribution('indico')
153        htdocsDir = indicoDist.get_resource_filename('indico', 'indico/htdocs')
154        etcDir = indicoDist.get_resource_filename('indico', 'etc')
155
156        # set defaults
157        config.reset({
158            'BaseURL': 'http://localhost:8000',
[011a92]159            'BaseSecureURL': '',
[cc5d1b]160            'UseXSendFile': False,
161            'AuthenticatorList': ['Local'],
[1b8324]162            'SmtpServer': ('localhost', 58025),
[cc5d1b]163            'SmtpUseTLS': 'no',
164            'DBConnectionParams': ('localhost', TestConfig.getInstance().getFakeDBPort()),
[2da75d]165            'LogDir': os.path.join(temp, 'log'),
166            'XMLCacheDir': os.path.join(temp, 'cache'),
[cc5d1b]167            'HtdocsDir': htdocsDir,
[2da75d]168            'ArchiveDir': os.path.join(temp, 'archive'),
[efefcc]169            'UploadedFilesTempDir': os.path.join(temp, 'tmp'),
[cc5d1b]170            'ConfigurationDir': etcDir
[2da75d]171            })
[28b84b]172
[2da75d]173        Config.setInstance(config)
174        self._cfg = config
[28b84b]175
[cc5d1b]176        # re-configure logging and template generator, so that paths are updated
177        from MaKaC.common import TemplateExec
178        from MaKaC.common.logger import Logger
179        TemplateExec.mako = TemplateExec._define_lookup()
180        Logger.reset()
181
182
[28b84b]183################## Start of DB Managing functions ##################
[2da75d]184    def _startManageDB(self):
185        port = TestConfig.getInstance().getFakeDBPort()
[49bc7c]186
[2da75d]187        self._info("Starting fake DB in port %s" % port)
188        self._startFakeDB('localhost', port)
[28b84b]189
[59779c]190    def _stopManageDB(self, killself=False):
[5e89ba]191        """
[2da75d]192        Stops the temporary DB
[5e89ba]193        """
[59779c]194        self._stopFakeDB(killself)
[28b84b]195
[49bc7c]196    def _startFakeDB(self, zeoHost, zeoPort):
[5e89ba]197        """
198        Starts a temporary DB in a different port
199        """
[49bc7c]200
201        print colored("-- Starting a test DB", "cyan")
202
[5e89ba]203        self._createNewDBFile()
204        self.zeoServer = TestManager._createDBServer(
[58c67a]205            os.path.join(self.dbFolder, "Data.fs"),
[49bc7c]206            zeoHost, zeoPort)
[58c67a]207
[59779c]208    def _stopFakeDB(self, killself=False):
[5e89ba]209        """
210        Stops the temporary DB
211        """
[49bc7c]212
[2da75d]213        print colored("-- Stopping test DB", "cyan")
[49bc7c]214
[28b84b]215        try:
[59779c]216            self.zeoServer.shutdown(killself)
[5e89ba]217            self._removeDBFile()
[28b84b]218        except OSError, e:
[87d5a6]219            print ("Problem terminating ZEO Server: " + str(e))
[28b84b]220
[5e89ba]221    def _createNewDBFile(self):
222        """
223        Creates a new DB file for a temporary DB
224        """
[28b84b]225        from ZODB import FileStorage, DB
226        savedDir = os.getcwd()
227        self.dbFolder = tempfile.mkdtemp()
228        os.chdir(self.dbFolder)
229
230        storage = FileStorage.FileStorage("Data.fs")
231        db = DB(storage)
232        connection = db.open()
233
234        transaction.commit()
235
236        connection.close()
237        db.close()
238        storage.close()
239        os.chdir(savedDir)
240
[5e89ba]241    def _removeDBFile(self):
242        """
243        Removes the files of the temporary DB
244        """
[28b84b]245        shutil.rmtree(self.dbFolder)
246
[2da75d]247    @classmethod
248    def _startSMTPServer(cls):
[1b8324]249        cls._smtpd = FakeMailThread(('localhost', 58025))
[2da75d]250        cls._smtpd.start()
251
252    @classmethod
253    def _stopSMTPServer(cls):
254        cls._smtpd.close()
255
[58c67a]256    @staticmethod
[49bc7c]257    def _createDBServer(dbFile, host, port):
[28b84b]258        """
259        Creates a fake DB server for testing
260        """
261
[87d5a6]262        # run a DB in a child process
263        from indico.tests.util import TestZEOServer
264        server = TestZEOServer(port, dbFile, hostname = host)
[cc5d1b]265        server.daemon = True
[87d5a6]266        server.start()
267        return server
[28b84b]268
269################## End of DB Managing functions ##################
Note: See TracBrowser for help on using the repository browser.