source: indico/indico/tests/core.py @ 28b84b

burotelhello-world-walkthroughipv6v0.98-seriesv0.98.2v0.98.3v0.98b1v0.98b2v0.99v1.0v1.1
Last change on this file since 28b84b was 28b84b, checked in by Pedro Ferreira <jose.pedro.ferreira@…>, 3 years ago

[IMP] Test framework: several improvements

  • Unit tests
    • fixed context manager tests;
    • added docstrings to both context manager and fossilize tests;
    • deactivated all the old tests waiting for refactoring;
    • created env module, that can be imported, in order to avoid the repetition of the setup/teardown functions for each test file;
  • PyLint?
    • changed the way the process is created, so that we can get the output in the console;
    • added file list, whitelist approach instead of ignores;
  • Rudimentary API - main classes exported from init directly;
  • Property mode set to 100644
File size: 8.6 KB
Line 
1# -*- coding: utf-8 -*-
2##
3## $Id$
4##
5## This file is part of CDS Indico.
6## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN.
7##
8## CDS Indico is free software; you can redistribute it and/or
9## modify it under the terms of the GNU General Public License as
10## published by the Free Software Foundation; either version 2 of the
11## License, or (at your option) any later version.
12##
13## CDS Indico is distributed in the hope that it will be useful, but
14## WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16## General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with CDS Indico; if not, write to the Free Software Foundation, Inc.,
20## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21
22
23# System modules
24import os, sys, socket, shutil, signal, commands, tempfile
25
26# Database
27import transaction
28from MaKaC.common.db import DBMgr
29
30# Indico
31from MaKaC.common.Configuration import Config
32
33from indico.tests.runners import *
34
35testRunnerDict = {'unit': UnitTestRunner,
36                  'functional': FunctionalTestRunner,
37                  'pylint': PylintTestRunner,
38                  'jsunit': JSUnitTestRunner,
39                  'jslint': JSLintTestRunner,
40                  'grid': GridTestRunner}
41
42class TestManager(object):
43    """
44    Main class, the heart of the test API.
45    Launches all the tests according to the parameters that are passed
46    """
47
48    __instance = None
49
50    def __init__(self):
51        self.dbmgr = None
52        self.zeoServer = None
53
54    def main(self, FakeDBManaging, testsToRun, options):
55
56        returnString = "\n\n=============== ~INDICOP SAYS~ ===============\n\n"
57
58        #To not pollute the installation of Indico
59        self.configureTempFolders()
60
61
62        self.startManageDB(FakeDBManaging)
63
64        if options['coverage']:
65            CoverageTestRunner.instantiate()
66
67        #specified test can either be unit or functional.
68        if options['specify']:
69            returnString += Specify(options['specify']).run()
70        else:
71            for test in testsToRun:
72                if test in testRunnerDict:
73                    print test
74                    returnString += testRunnerDict[test](**options).run()
75                else:
76                    returnString += ("[ERR] Test set '%s' does not exist. "
77                      "It has to be added in the testRunnerDict variable\n") % test
78
79
80        self.stopManageDB(FakeDBManaging)
81
82        return returnString
83
84    def configureTempFolders(self):
85        keyNames = [#'LogDir',
86                    'ArchiveDir',
87                    'UploadedFilesTempDir']
88        self.newValues = {}
89
90        for key in keyNames:
91            self.newValues[key] = tempfile.mkdtemp()
92
93        Config.getInstance().updateValues(self.newValues)
94
95    def deleteTempFolders(self):
96        for k in self.newValues:
97            shutil.rmtree(self.newValues[k])
98
99################## Start of DB Managing functions ##################
100    def startManageDB(self, FakeDBManaging):
101        """FakeDBManaging == 0, the tests to run do not need any DB
102        FakeDBManaging == 1, unit tests need a fake DB that can be run in parallel
103        of the production DB
104        FakeDBManaging == 2, production DB is not running and functional tests
105        need fake DB which is going to be run on production port.
106        FakeDBManaging == 3, production DB is running, we need to stop it and
107        and start a fake DB on the production port. we will restart production DB"""
108        if FakeDBManaging == 1:
109            self.startFakeDB(TestConfig.getInstance().getFakeDBPort())
110            self.createDummyUser()
111        elif FakeDBManaging == 2:
112            self.startFakeDB(Config.getInstance().getDBConnectionParams()[1])
113            self.createDummyUser()
114        elif FakeDBManaging == 3:
115            self.stopProductionDB()
116            self.startFakeDB(Config.getInstance().getDBConnectionParams()[1])
117            self.createDummyUser()
118
119    def stopManageDB(self, FakeDBManaging):
120        if FakeDBManaging == 1 or FakeDBManaging == 2:
121            self.stopFakeDB()
122            self.restoreDBInstance()
123        elif FakeDBManaging == 3:
124            self.stopFakeDB()
125            self.startProductionDB()
126            self.restoreDBInstance()
127
128    def startFakeDB(self, zeoPort):
129        self.createNewDBFile()
130        self.zeoServer = self.createDBServer(os.path.join(self.dbFolder, "Data.fs"),
131                                             zeoPort)
132        DBMgr.setInstance(DBMgr(hostname="localhost", port=zeoPort))
133
134    def stopFakeDB(self):
135        try:
136            os.kill(self.zeoServer, signal.SIGINT)
137        except OSError, e:
138            print ("Problem sending kill signal: " + str(e))
139
140        try:
141            os.waitpid(self.zeoServer, 0)
142            self.removeDBFile()
143        except OSError, e:
144            print ("Problem waiting for ZEO Server: " + str(e))
145
146    def restoreDBInstance(self):
147        DBMgr.setInstance(None)
148
149    def startProductionDB(self):
150        try:
151            commands.getstatusoutput(TestConfig.getInstance().getStartDBCmd())
152        except KeyError:
153            print "[ERR] Not found in tests.conf: command to start production DB\n"
154            sys.exit(1)
155
156    def stopProductionDB(self):
157        try:
158            commands.getstatusoutput(TestConfig.getInstance().getStopDBCmd())
159        except KeyError:
160            print "[ERR] Not found in tests.conf: command to stop production DB\n"
161            sys.exit(1)
162
163    def createNewDBFile(self):
164        from ZODB import FileStorage, DB
165        savedDir = os.getcwd()
166        self.dbFolder = tempfile.mkdtemp()
167        os.chdir(self.dbFolder)
168
169        storage = FileStorage.FileStorage("Data.fs")
170        db = DB(storage)
171        connection = db.open()
172        dbroot = connection.root()
173
174        transaction.commit()
175
176        connection.close()
177        db.close()
178        storage.close()
179        os.chdir(savedDir)
180
181    def removeDBFile(self):
182        shutil.rmtree(self.dbFolder)
183
184    def createDBServer(self, file, port):
185        """
186        Creates a fake DB server for testing
187        """
188
189        pid = os.fork()
190        if pid:
191            return pid
192        else:
193            # run a DB in a child process
194            from indico.tests.util import TestZEOServer
195            server = TestZEOServer(port, file)
196            server.start()
197
198################## End of DB Managing functions ##################
199
200    def createDummyUser(self):
201        from MaKaC import user
202        from MaKaC.authentication import AuthenticatorMgr
203        from MaKaC.common import HelperMaKaCInfo
204        from MaKaC.common import indexes
205        DBMgr.getInstance().startRequest()
206
207        #filling info to new user
208        avatar = user.Avatar()
209        avatar.setName( "fake" )
210        avatar.setSurName( "fake" )
211        avatar.setOrganisation( "fake" )
212        avatar.setLang( "en_US" )
213        avatar.setEmail( "fake@fake.fake" )
214
215        #registering user
216        ah = user.AvatarHolder()
217        ah.add(avatar)
218
219        #setting up the login info
220        li = user.LoginInfo( "dummyuser", "dummyuser" )
221        ih = AuthenticatorMgr()
222        userid = ih.createIdentity( li, avatar, "Local" )
223        ih.add( userid )
224
225        #activate the account
226        avatar.activateAccount()
227
228        #since the DB is empty, we have to add dummy user as admin
229        minfo = HelperMaKaCInfo.getMaKaCInfoInstance()
230        al = minfo.getAdminList()
231        al.grant( avatar )
232
233        DBMgr.getInstance().endRequest()
234
235    def deleteDummyUser(self):
236        from MaKaC import user
237        from MaKaC.authentication import AuthenticatorMgr
238        from MaKaC.common import HelperMaKaCInfo
239        from MaKaC.common import indexes
240        DBMgr.getInstance().startRequest()
241
242        #removing user from admin list
243        minfo = HelperMaKaCInfo.getMaKaCInfoInstance()
244        al = minfo.getAdminList()
245        ah = user.AvatarHolder()
246        avatar = ah.match({'email':'fake@fake.fake'})[0]
247        al.revoke( avatar )
248
249        #remove the login info
250        userid = avatar.getIdentityList()[0]
251        ih = AuthenticatorMgr()
252        ih.removeIdentity(userid)
253
254        #unregistering the user info
255        index = indexes.IndexesHolder().getById("email")
256        index.unindexUser(avatar)
257        index = indexes.IndexesHolder().getById("name")
258        index.unindexUser(avatar)
259        index = indexes.IndexesHolder().getById("surName")
260        index.unindexUser(avatar)
261        index = indexes.IndexesHolder().getById("organisation")
262        index.unindexUser(avatar)
263        index = indexes.IndexesHolder().getById("status")
264        index.unindexUser(avatar)
Note: See TracBrowser for help on using the repository browser.