Changeset 574b7d in indico


Ignore:
Timestamp:
06/18/10 18:59:00 (3 years ago)
Author:
Pedro Ferreira <jose.pedro.ferreira@…>
Branches:
master, burotel, hello-world-walkthrough, ipv6, v0.98-series, v0.98.2, v0.98.3, v0.98b1, v0.98b2, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, 0da0c1403bae8e51d8229f460181c71b9e6dda72
Children:
b5b039
Parents:
49bc7c
git-author:
Pedro Ferreira <jose.pedro.ferreira@…> (06/07/10 18:12:46)
git-committer:
Pedro Ferreira <jose.pedro.ferreira@…> (06/18/10 18:59:00)
Message:

[IMP] Test Framework: Several improvements

  • Parallel selenium grid tests are now possible;
  • Refactored I/O handling methods;
  • Changed selenium grid data structure;
  • Fixes plugin tests;
  • "Specify" and "HTML" options restructured;
  • Added some needed init.py;
  • Some more linting;
  • Added some selenium helpers;
  • Added Ajax debugging capability to Presentation;
  • Better file path computing functions (borrowed);
  • JSUnit and JSLint tests adapted;
  • Changed --full-output to --silent;
Files:
4 added
23 edited
1 copied
3 moved

Legend:

Unmodified
Added
Removed
  • indico/MaKaC/common/fossilize.py

    r5e89ba r574b7d  
    205205 
    206206    @classmethod 
    207     def _fossilizeIterable(cls, target, interface, useAttrCache = False, **kwargs): 
     207    def fossilizeIterable(cls, target, interface, useAttrCache = False, **kwargs): 
    208208        """ 
    209209        Fossilizes an object, be it a 'direct' fossilizable 
     
    220220                container = {} 
    221221                for key, value in target.iteritems(): 
    222                     container[key] = fossilize(value, interface, useAttrCache, **kwargs) 
     222                    container[key] = fossilize(value, interface, useAttrCache, 
     223                                               **kwargs) 
    223224                return container 
    224225            elif hasattr(target, '__iter__'): 
    225                 #we turn sets and tuples into lists since JSON does not have sets / tuples 
     226                # we turn sets and tuples into lists since JSON does not 
     227                # have sets / tuples 
    226228                return list(fossilize(elem, 
    227229                                      interface, 
     
    285287                #targetInterface = globals()[targetInterfaceName] 
    286288 
    287                 methodResult = Fossilizable._fossilizeIterable( 
     289                methodResult = Fossilizable.fossilizeIterable( 
    288290                    methodResult, targetInterface, **kwargs) 
    289291 
     
    351353    :type useAttrCache: boolean 
    352354    """ 
    353     return Fossilizable._fossilizeIterable(target, interfaceArg, useAttrCache, **kwargs) 
     355    return Fossilizable.fossilizeIterable(target, interfaceArg, useAttrCache, 
     356                                           **kwargs) 
  • indico/MaKaC/plugins/Collaboration/Vidyo/tests/python/unit/common_test.py

    rc18126 r574b7d  
    2020import unittest 
    2121from MaKaC.common.db import DBMgr 
    22 from MaKaC.plugins.Collaboration.Vidyo.common import AdminClient, UserClient 
     22from MaKaC.plugins.Collaboration.Vidyo.api.client import AdminClient, UserClient 
    2323from MaKaC.i18n import _ 
    2424from MaKaC.plugins.Collaboration.Vidyo.tests.python.unit.vidyoTestTools import VidyoTestSetup 
  • indico/MaKaC/plugins/Collaboration/Vidyo/tests/python/unit/vidyoTestTools.py

    r2f05ce r574b7d  
    1717## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
    1818## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     19 
    1920from MaKaC.plugins.base import PluginsHolder 
    2021from MaKaC.plugins.Collaboration.collaborationTools import CollaborationTools 
     
    2526    def setup(cls): 
    2627 
    27         # lazy loading, as the plugin system imports everything, and we really 
    28         # don't need this, except for testing 
    29         from TestsConfig import TestsConfig 
     28        # lazy import because we don't want it to be imported by default 
     29        # (as the plugin system currently loads all submodules) 
     30        from indico.tests.config import TestConfig 
    3031 
    3132        PluginsHolder().loadAllPlugins() 
    3233 
    33         testConfig = TestsConfig.getInstance() 
     34        testConfig = TestConfig.getInstance() 
    3435        vidyoOptions = CollaborationTools.getPlugin("Vidyo").getOptions() 
    3536 
  • indico/htdocs/js/presentation/Data/Remote.js

    reb7c79 r574b7d  
    33 * @author Tom 
    44 */ 
     5 
     6var activeWebRequests = 0 
    57 
    68/** 
     
    236238                                return; 
    237239                        } 
     240                        activeWebRequests--; 
    238241                        delete transport.onreadystatechange; 
    239242                        var status = transport.status; 
     
    245248                } 
    246249                transport.send(body); 
     250                activeWebRequests++; 
    247251        } catch (e) { 
    248252                handler(null, e); 
  • indico/tests/base.py

    r49bc7c r574b7d  
    3535from indico.tests.config import TestConfig 
    3636 
    37 class BaseTestRunner(object): 
     37 
     38class TestOptionException(Exception): 
     39    """ 
     40    Raised when a particular runner doesn't support an option 
     41    """ 
     42 
     43class IOMixin(object): 
     44    """ 
     45    Mixin class that provides some simple utility functions 
     46    for error/info messages in the console 
     47    """ 
     48 
     49    @classmethod 
     50    def _info(cls, message): 
     51        """ 
     52        Prints an info message 
     53        """ 
     54        print colored("** %s" % message, 'blue') 
     55 
     56    @classmethod 
     57    def _success(cls, message): 
     58        """ 
     59        Prints an info message 
     60        """ 
     61        print colored("** %s" % message, 'green') 
     62 
     63    @classmethod 
     64    def _error(cls, message): 
     65        """ 
     66        Prints an error message 
     67        """ 
     68        print colored("** %s" % message, 'red') 
     69 
     70 
     71class OptionProxy(object): 
     72    """ 
     73    Encapsulates all the options present in a TestRunner, 
     74    providing a common access point, and controlling some 
     75    "hot spots" as well 
     76    """ 
     77 
     78    def __init__(self, allowedOptions): 
     79        self._optionTable = allowedOptions 
     80        self._options = {} 
     81 
     82    def call(self, runner, event, *args): 
     83        """ 
     84        Invoked from a code hot spot, so that the option can 
     85        perform operations 
     86        """ 
     87 
     88        for option in self._options.values(): 
     89            if hasattr(option, event) and option.shouldExecute(): 
     90                getattr(option, event)(runner, *args) 
     91 
     92    def configure(self, **kwargs): 
     93        """ 
     94        Initializes the options based on command line parameters 
     95        """ 
     96 
     97        for optName, optClass  in self._optionTable.iteritems(): 
     98            if optName in kwargs: 
     99                self._options[optName] = optClass(kwargs[optName]) 
     100            else: 
     101                self._options[optName] = optClass(False) 
     102 
     103        for optName in kwargs: 
     104            if optName not in self._optionTable: 
     105                raise TestOptionException("Option '%s' not allowed here!" % 
     106                                          optName) 
     107 
     108 
     109    def valueOf(self, optName): 
     110        """ 
     111        Returns the direct value of an option 
     112        """ 
     113        if optName in self._options: 
     114            return self._options[optName].value 
     115        else: 
     116            return None 
     117 
     118 
     119class Option(IOMixin): 
     120    """ 
     121    Represents an option for a TestRunner 
     122    """ 
     123 
     124    def __init__(self, value): 
     125        self.value = value 
     126 
     127    def shouldExecute(self): 
     128        """ 
     129        Determines if the Option should be taken into account (hot spots), 
     130        depending on the context 
     131        """ 
     132        return True 
     133 
     134 
     135class BaseTestRunner(IOMixin): 
    38136    """ 
    39137    Base class for all other TestRunners. 
     
    41139    """ 
    42140 
     141    # overloaded for each runner, contains allowed options for each runner 
     142 
     143    # for this case: 
     144    #   * silent - True if the output shouldn't be redirected to the console 
     145 
     146    _runnerOptions = {'silent': Option} 
     147 
    43148    # path to this current file 
    44149    setupDir = os.path.dirname(__file__) 
     
    48153        Options can be passed as kwargs, currently the following is supported: 
    49154 
    50          * verbose - if the output should be redirected to the console in 
    51         addition to the log file; 
    52         """ 
    53  
    54         self.options = kwargs 
     155        """ 
     156 
    55157        self.err = None 
    56158        self.out = None 
     
    58160        # make a TestConfig instance available everywhere 
    59161        self.config = TestConfig.getInstance() 
     162 
     163        # initialize allowed options 
     164        self.options = OptionProxy(self._runnerOptions) 
     165        self.options.configure(**kwargs) 
    60166 
    61167    def _run(self): 
     
    75181        description =  self.__doc__.strip().split('\n')[0] 
    76182 
    77         print colored("** Running %s" % description, 'yellow', attrs = ['bold']) 
    78  
    79         return self._run() 
    80  
    81     def info(self, message): 
    82         """ 
    83         Prints an info message 
    84         """ 
    85         print colored("** %s" % message, 'blue') 
     183        self._startIOCapture() 
     184 
     185        self._info("Running %s" % description) 
     186 
     187        self._callOptions('pre_run') 
     188        result = self._run() 
     189        self._callOptions('post_run') 
     190 
     191        if result: 
     192            self._success("%s successful!" % description) 
     193        else: 
     194            self._error("%s failed!" % description) 
     195 
     196        # ask the option handlers to compute a final message 
     197        self._callOptions('final_message') 
     198        self._writeReport(self.__class__.__name__, 
     199                          self._finishIOCapture()) 
     200 
     201        return result 
    86202 
    87203    def _startIOCapture(self): 
     
    92208        """ 
    93209 
    94         if self.options['verbose']: 
    95             # capture I/O but display it as well 
    96             self.err = TeeStringIO(sys.stderr) 
    97             self.out = TeeStringIO(sys.stdout) 
    98         else: 
     210        if self.options.valueOf('silent'): 
    99211            # just capture it 
    100212            self.err = StringIO.StringIO() 
    101             self.out = StringIO.StringIO() 
     213            self.out = self.err 
     214        else: 
     215            # capture I/O but display it as well 
     216            self.out = TeeStringIO(sys.stdout) 
     217            self.err = TeeStringIO(sys.stderr, targetStream = self.out) 
    102218        sys.stderr = self.err 
    103219        sys.stdout = self.out 
    104220 
    105221 
     222 
    106223    def _finishIOCapture(self): 
    107224        """ 
     
    111228        sys.stdout = sys.__stdout__ 
    112229 
    113         return (self.out.getvalue(), 
    114                 self.err.getvalue()) 
     230        return self.out.getvalue() 
    115231 
    116232    @staticmethod 
     
    125241            print data, 
    126242 
    127     def writeReport(self, filename, content): 
     243    def _writeReport(self, filename, content): 
    128244        """ 
    129245        Write the test report, using the filename and content that are passed 
    130246        """ 
     247        filePath = os.path.join(self.setupDir, 'report', filename + ".txt") 
    131248        try: 
    132             f = open(os.path.join(self.setupDir, 'report', filename + ".txt"), 'w') 
     249            f = open(filePath, 'w') 
    133250            f.write(content) 
    134251            f.close() 
    135             return "" 
    136252        except IOError: 
    137253            return "Unable to write in %s, check your file permissions." % \ 
    138254                    os.path.join(self.setupDir, 'report', filename + ".txt") 
    139255 
     256        self._info("report in %s" % filePath) 
     257 
    140258    @staticmethod 
    141259    def walkThroughFolders(rootPath, foldersPattern): 
     
    152270 
    153271        return foldersArray 
     272 
     273    def _callOptions(self, method, *args): 
     274        """ 
     275        Invokes the option proxy, providing the hot spot with name 'method', 
     276        that options should have extended 
     277        """ 
     278 
     279        # invoke the option proxy 
     280        self.options.call(self, method, *args) 
     281 
     282 
  • indico/tests/core.py

    r49bc7c r574b7d  
    4141from indico.tests.config import TestConfig 
    4242from indico.tests.runners import * 
     43from indico.tests.base import TestOptionException 
    4344 
    4445TEST_RUNNERS = {'unit': UnitTestRunner, 
     
    6869 
    6970    @staticmethod 
     71    def _title(text): 
     72        """ 
     73        Prints an title 
     74        """ 
     75        print colored("-- " + str(text), 'yellow', attrs=['bold']) 
     76 
     77    @staticmethod 
    7078    def _info(message): 
    7179        """ 
     
    7381        """ 
    7482        print colored("-- " + str(message), 'cyan') 
     83 
     84    @staticmethod 
     85    def _error(message): 
     86        """ 
     87        Prints an info message 
     88        """ 
     89        print colored("-- " + str(message), 'red') 
    7590 
    7691    @staticmethod 
     
    89104         * options - test options (such as verbosity...) 
    90105        """ 
    91  
    92         returnString = "\n\n%s\n\n" % colored('** Results', 'blue', attrs = ['bold']) 
     106        result = False 
     107 
     108        print 
     109        TestManager._title("Starting test framework\n") 
    93110 
    94111        #To not pollute the installation of Indico 
     
    97114        self._startManageDB(fakeDBPolicy) 
    98115 
    99         if options['coverage']: 
    100             CoverageTestRunner.instantiate() 
    101  
    102         #specified test can either be unit or functional. 
    103         if options['specify']: 
    104             returnString += SpecificFunctionalTestRunner(options['specify']).run() 
     116        for test in testsToRun: 
     117            if test in TEST_RUNNERS: 
     118                try: 
     119                    result = TEST_RUNNERS[test](**options).run() 
     120                except TestOptionException, e: 
     121                    TestManager._error(e) 
     122            else: 
     123                print colored("[ERR] Test set '%s' does not exist. " 
     124                              "It has to be added in the TEST_RUNNERS variable\n", 
     125                              'red') % test 
     126 
     127        self._stopManageDB(fakeDBPolicy) 
     128 
     129        self._deleteTempFolders() 
     130 
     131        if result: 
     132            return 0 
    105133        else: 
    106             for test in testsToRun: 
    107                 if test in TEST_RUNNERS: 
    108                     returnString += TEST_RUNNERS[test](**options).run() 
    109                 else: 
    110                     returnString += colored("[ERR] Test set '%s' does not exist. " 
    111                       "It has to be added in the TEST_RUNNERS variable\n", 'red') \ 
    112                     % test 
    113  
    114  
    115         self._stopManageDB(fakeDBPolicy) 
    116  
    117         self._deleteTempFolders() 
    118  
    119         return returnString 
     134            return -1 
    120135 
    121136    def _configureTempFolders(self): 
     
    158173        if fakeDBPolicy == 1: 
    159174            self._info("Starting fake DB in non-standard port") 
    160             self._startFakeDB(TestConfig.getInstance().getFakeDBPort()) 
     175            self._startFakeDB('localhost', TestConfig.getInstance().getFakeDBPort()) 
    161176            TestManager._createDummyUser() 
    162177        elif fakeDBPolicy == 2: 
     
    165180            TestManager._createDummyUser() 
    166181        elif fakeDBPolicy == 3: 
    167             self._info("Stopping production DB and Starting fake DB in standard port") 
     182            self._info("Stopping production DB and" + 
     183                       " Starting fake DB in standard port") 
    168184            TestManager._stopProductionDB() 
    169185            self._startFakeDB(params[0], params[1]) 
     
    242258        TestManager._info("Stopping production DB") 
    243259        try: 
    244             TestManager._debug(commands.getstatusoutput(TestConfig.getInstance().getStopDBCmd())) 
     260            TestManager._debug( 
     261                commands.getstatusoutput( 
     262                    TestConfig.getInstance().getStopDBCmd())) 
    245263        except KeyError: 
    246264            print "[ERR] Not found in tests.conf: command to stop production DB\n" 
  • indico/tests/javascript/unit/confTemplate.conf

    rce5cca r574b7d  
    77  # Order taken from indico/Loader.js 
    88  # presentation/Loader.js 
    9   - ../../../indico/htdocs/js/presentation/Core/Primitives.js 
    10   - ../../../indico/htdocs/js/presentation/Core/Exception.js 
    11   - ../../../indico/htdocs/js/presentation/Core/Iterators.js 
    12   - ../../../indico/htdocs/js/presentation/Core/Tools.js 
    13   - ../../../indico/htdocs/js/presentation/Core/String.js 
    14   - ../../../indico/htdocs/js/presentation/Core/Type.js 
    15   - ../../../indico/htdocs/js/presentation/Core/Interfaces.js 
    16   - ../../../indico/htdocs/js/presentation/Core/Commands.js 
    17   - ../../../indico/htdocs/js/presentation/Core/MathEx.js 
    18   - ../../../indico/htdocs/js/presentation/Data/Bag.js 
    19   - ../../../indico/htdocs/js/presentation/Data/Watch.js 
    20   - ../../../indico/htdocs/js/presentation/Data/WatchValue.js 
    21   - ../../../indico/htdocs/js/presentation/Data/WatchList.js 
    22   - ../../../indico/htdocs/js/presentation/Data/WatchObject.js 
    23   - ../../../indico/htdocs/js/presentation/Data/Binding.js 
    24   - ../../../indico/htdocs/js/presentation/Data/Logic.js 
    25   - ../../../indico/htdocs/js/presentation/Data/Json.js 
    26   - ../../../indico/htdocs/js/presentation/Data/Remote.js 
    27   - ../../../indico/htdocs/js/presentation/Data/DataStore.js 
    28   - ../../../indico/htdocs/js/presentation/Data/DateTime.js 
    29   - ../../../indico/htdocs/js/presentation/Data/Cookies.js 
    30   - ../../../indico/htdocs/js/presentation/Ui/MimeTypes.js 
    31   - ../../../indico/htdocs/js/presentation/Ui/Dom.js 
    32   - ../../../indico/htdocs/js/presentation/Ui/XElement.js 
    33   - ../../../indico/htdocs/js/presentation/Ui/Html.js 
    34   - ../../../indico/htdocs/js/presentation/Ui/Color.js 
    35   - ../../../indico/htdocs/js/presentation/Ui/Text.js 
    36   - ../../../indico/htdocs/js/presentation/Ui/StyleSheet.js 
    37   - ../../../indico/htdocs/js/presentation/Ui/Extensions/SimpleStyles.js 
    38   - ../../../indico/htdocs/js/presentation/Ui/Extensions/Layout.js 
    39   - ../../../indico/htdocs/js/presentation/Ui/Extensions/Lookup.js 
    40   - ../../../indico/htdocs/js/presentation/Ui/Draw/Drawing.js 
    41   - ../../../indico/htdocs/js/presentation/Ui/Draw/Svg.js 
    42   - ../../../indico/htdocs/js/presentation/Ui/Draw/Vml.js 
    43   - ../../../indico/htdocs/js/presentation/Ui/Draw/Draw.js 
    44   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetBase.js 
    45   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetPage.js 
    46   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetComponents.js 
    47   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetControl.js 
    48   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetEditor.js 
    49   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetTable.js 
    50   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetField.js 
    51   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetEditable.js 
    52   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetMenu.js 
    53   - ../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetGrid.js 
     9  - ../../../../indico/htdocs/js/presentation/Core/Primitives.js 
     10  - ../../../../indico/htdocs/js/presentation/Core/Exception.js 
     11  - ../../../../indico/htdocs/js/presentation/Core/Iterators.js 
     12  - ../../../../indico/htdocs/js/presentation/Core/Tools.js 
     13  - ../../../../indico/htdocs/js/presentation/Core/String.js 
     14  - ../../../../indico/htdocs/js/presentation/Core/Type.js 
     15  - ../../../../indico/htdocs/js/presentation/Core/Interfaces.js 
     16  - ../../../../indico/htdocs/js/presentation/Core/Commands.js 
     17  - ../../../../indico/htdocs/js/presentation/Core/MathEx.js 
     18  - ../../../../indico/htdocs/js/presentation/Data/Bag.js 
     19  - ../../../../indico/htdocs/js/presentation/Data/Watch.js 
     20  - ../../../../indico/htdocs/js/presentation/Data/WatchValue.js 
     21  - ../../../../indico/htdocs/js/presentation/Data/WatchList.js 
     22  - ../../../../indico/htdocs/js/presentation/Data/WatchObject.js 
     23  - ../../../../indico/htdocs/js/presentation/Data/Binding.js 
     24  - ../../../../indico/htdocs/js/presentation/Data/Logic.js 
     25  - ../../../../indico/htdocs/js/presentation/Data/Json.js 
     26  - ../../../../indico/htdocs/js/presentation/Data/Remote.js 
     27  - ../../../../indico/htdocs/js/presentation/Data/DataStore.js 
     28  - ../../../../indico/htdocs/js/presentation/Data/DateTime.js 
     29  - ../../../../indico/htdocs/js/presentation/Data/Cookies.js 
     30  - ../../../../indico/htdocs/js/presentation/Ui/MimeTypes.js 
     31  - ../../../../indico/htdocs/js/presentation/Ui/Dom.js 
     32  - ../../../../indico/htdocs/js/presentation/Ui/XElement.js 
     33  - ../../../../indico/htdocs/js/presentation/Ui/Html.js 
     34  - ../../../../indico/htdocs/js/presentation/Ui/Color.js 
     35  - ../../../../indico/htdocs/js/presentation/Ui/Text.js 
     36  - ../../../../indico/htdocs/js/presentation/Ui/StyleSheet.js 
     37  - ../../../../indico/htdocs/js/presentation/Ui/Extensions/SimpleStyles.js 
     38  - ../../../../indico/htdocs/js/presentation/Ui/Extensions/Layout.js 
     39  - ../../../../indico/htdocs/js/presentation/Ui/Extensions/Lookup.js 
     40  - ../../../../indico/htdocs/js/presentation/Ui/Draw/Drawing.js 
     41  - ../../../../indico/htdocs/js/presentation/Ui/Draw/Svg.js 
     42  - ../../../../indico/htdocs/js/presentation/Ui/Draw/Vml.js 
     43  - ../../../../indico/htdocs/js/presentation/Ui/Draw/Draw.js 
     44  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetBase.js 
     45  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetPage.js 
     46  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetComponents.js 
     47  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetControl.js 
     48  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetEditor.js 
     49  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetTable.js 
     50  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetField.js 
     51  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetEditable.js 
     52  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetMenu.js 
     53  - ../../../../indico/htdocs/js/presentation/Ui/Widgets/WidgetGrid.js 
    5454 
    5555 
    5656  # indico/Core/Loader.js 
    57   - ../../../indico/htdocs/js/indico/Core/Components.js 
    58   - ../../../indico/htdocs/js/indico/Core/Data.js 
    59   - ../../../indico/htdocs/js/indico/Core/Presentation.js 
    60   - ../../../indico/htdocs/js/indico/Core/Browser.js 
    61   - ../../../indico/htdocs/js/indico/Core/Services.js 
    62   - ../../../indico/htdocs/js/indico/Core/Auxiliar.js 
    63   - ../../../indico/htdocs/js/indico/Core/Effects.js 
    64   - ../../../indico/htdocs/js/indico/Core/Buttons.js 
    65   - ../../../indico/htdocs/js/indico/Core/Interaction/Base.js 
    66   - ../../../indico/htdocs/js/indico/Core/Widgets/Base.js 
    67   - ../../../indico/htdocs/js/indico/Core/Widgets/Inline.js 
    68   - ../../../indico/htdocs/js/indico/Core/Widgets/Menu.js 
    69   - ../../../indico/htdocs/js/indico/Core/Widgets/Navigation.js 
    70   - ../../../indico/htdocs/js/indico/Core/Widgets/RichText.js 
    71   - ../../../indico/htdocs/js/indico/Core/Dialogs/Popup.js 
    72   - ../../../indico/htdocs/js/indico/Core/Dialogs/Base.js 
    73   - ../../../indico/htdocs/js/indico/Core/Dialogs/Util.js 
     57  - ../../../../indico/htdocs/js/indico/Core/Components.js 
     58  - ../../../../indico/htdocs/js/indico/Core/Data.js 
     59  - ../../../../indico/htdocs/js/indico/Core/Presentation.js 
     60  - ../../../../indico/htdocs/js/indico/Core/Browser.js 
     61  - ../../../../indico/htdocs/js/indico/Core/Services.js 
     62  - ../../../../indico/htdocs/js/indico/Core/Auxiliar.js 
     63  - ../../../../indico/htdocs/js/indico/Core/Effects.js 
     64  - ../../../../indico/htdocs/js/indico/Core/Buttons.js 
     65  - ../../../../indico/htdocs/js/indico/Core/Interaction/Base.js 
     66  - ../../../../indico/htdocs/js/indico/Core/Widgets/Base.js 
     67  - ../../../../indico/htdocs/js/indico/Core/Widgets/Inline.js 
     68  - ../../../../indico/htdocs/js/indico/Core/Widgets/Menu.js 
     69  - ../../../../indico/htdocs/js/indico/Core/Widgets/Navigation.js 
     70  - ../../../../indico/htdocs/js/indico/Core/Widgets/RichText.js 
     71  - ../../../../indico/htdocs/js/indico/Core/Dialogs/Popup.js 
     72  - ../../../../indico/htdocs/js/indico/Core/Dialogs/Base.js 
     73  - ../../../../indico/htdocs/js/indico/Core/Dialogs/Util.js 
    7474 
    7575 
    7676  # indico/Legacy/Loader.js 
    77   - ../../../indico/htdocs/js/indico/Legacy/Widgets.js 
    78   - ../../../indico/htdocs/js/indico/Legacy/Dialogs.js 
    79   - ../../../indico/htdocs/js/indico/Legacy/Util.js 
     77  - ../../../../indico/htdocs/js/indico/Legacy/Widgets.js 
     78  - ../../../../indico/htdocs/js/indico/Legacy/Dialogs.js 
     79  - ../../../../indico/htdocs/js/indico/Legacy/Util.js 
    8080 
    8181 
    8282  # indico/Management/Loader.js 
    83   - ../../../indico/htdocs/js/indico/Management/RoomBooking.js 
    84   - ../../../indico/htdocs/js/indico/Management/ConfModifDisplay.js 
    85   - ../../../indico/htdocs/js/indico/Management/Users.js 
    86   - ../../../indico/htdocs/js/indico/Management/eventCreation.js 
    87   - ../../../indico/htdocs/js/indico/Management/Timetable.js 
     83  - ../../../../indico/htdocs/js/indico/Management/RoomBooking.js 
     84  - ../../../../indico/htdocs/js/indico/Management/ConfModifDisplay.js 
     85  - ../../../../indico/htdocs/js/indico/Management/Users.js 
     86  - ../../../../indico/htdocs/js/indico/Management/eventCreation.js 
     87  - ../../../../indico/htdocs/js/indico/Management/Timetable.js 
    8888 
    8989 
    9090  # indico/Admin/Loader.js 
    91   - ../../../indico/htdocs/js/indico/Admin/News.js 
    92   - ../../../indico/htdocs/js/indico/Admin/Upcoming.js 
     91  - ../../../../indico/htdocs/js/indico/Admin/News.js 
     92  - ../../../../indico/htdocs/js/indico/Admin/Upcoming.js 
    9393 
    9494 
    9595  # indico/MaterialEditor/Loader.js 
    96   - ../../../indico/htdocs/js/indico/MaterialEditor/Editor.js 
     96  - ../../../../indico/htdocs/js/indico/MaterialEditor/Editor.js 
    9797 
    9898 
    9999  # indico/Timetable/Loader.js 
    100   - ../../../indico/htdocs/js/indico/Timetable/Layout.js 
    101   - ../../../indico/htdocs/js/indico/Timetable/Draw.js 
    102   - ../../../indico/htdocs/js/indico/Timetable/Management.js 
    103   - ../../../indico/htdocs/js/indico/Timetable/Filter.js 
    104   - ../../../indico/htdocs/js/indico/Timetable/Base.js 
     100  - ../../../../indico/htdocs/js/indico/Timetable/Layout.js 
     101  - ../../../../indico/htdocs/js/indico/Timetable/Draw.js 
     102  - ../../../../indico/htdocs/js/indico/Timetable/Management.js 
     103  - ../../../../indico/htdocs/js/indico/Timetable/Filter.js 
     104  - ../../../../indico/htdocs/js/indico/Timetable/Base.js 
    105105 
    106106 
    107107  # indico/Common/Loader.js 
    108   - ../../../indico/htdocs/js/indico/Common/TimezoneSelector.js 
    109   - ../../../indico/htdocs/js/indico/Common/IntelligentSearchBox.js 
     108  - ../../../../indico/htdocs/js/indico/Common/TimezoneSelector.js 
     109  - ../../../../indico/htdocs/js/indico/Common/IntelligentSearchBox.js 
    110110 
    111111 
    112112  # indico/Collaboration/Loader.js 
    113   - ../../../indico/htdocs/js/indico/Collaboration/Collaboration.js 
     113  - ../../../../indico/htdocs/js/indico/Collaboration/Collaboration.js 
    114114 
    115115 
    116116  # indico/Display/Dialogs.js 
    117   - ../../../indico/htdocs/js/indico/Display/Dialogs.js 
     117  - ../../../../indico/htdocs/js/indico/Display/Dialogs.js 
    118118 
    119119 
  • indico/tests/python/__init__.py

    r5e89ba r574b7d  
    2121 
    2222""" 
    23 Modifies the location of indico.conf referenced inside makacconfigpy_path to 
    24 point to indico_conf_path 
     23Test suite for all the Indico Python code 
    2524""" 
    26 import os 
    27 import re 
    28 fdata = open(os.path.join('indico', 'MaKaC', 'common', 'MaKaCConfig.py')).read() 
    29 fdata = re.sub('indico_conf[ ]*=[ ]*[\'"]{1}([^\'"]*)[\'"]{1}', 
    30                "indico_conf = \"%s\"" % os.path.join('etc', 'indico.conf'), fdata) 
    31 open(os.path.join('indico', 'MaKaC', 'common', 'MaKaCConfig.py'), 'w').write(fdata) 
  • indico/tests/python/functional/__init__.py

    r28b84b r574b7d  
    11# -*- coding: utf-8 -*- 
    22## 
     3## $Id$ 
    34## 
    45## This file is part of CDS Indico. 
     
    1920## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2021 
    21 import unittest 
    22 import threading, time 
    23  
    24 from MaKaC.common.contextManager import ContextManager 
    25  
    26  
    27 if __name__ == '__main__': 
    28     unittest.main() 
     22""" 
     23This module provides the functional tests that will be executed. 
     24It uses selenium rc and selenium grid. 
     25""" 
  • indico/tests/python/functional/example_test.py

    r49bc7c r574b7d  
     1# -*- coding: utf-8 -*- 
     2## 
     3## 
     4## This file is part of CDS Indico. 
     5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. 
     6## 
     7## CDS Indico is free software; you can redistribute it and/or 
     8## modify it under the terms of the GNU General Public License as 
     9## published by the Free Software Foundation; either version 2 of the 
     10## License, or (at your option) any later version. 
     11## 
     12## CDS Indico is distributed in the hope that it will be useful, but 
     13## WITHOUT ANY WARRANTY; without even the implied warranty of 
     14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     15## General Public License for more details. 
     16## 
     17## You should have received a copy of the GNU General Public License 
     18## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
     19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     20 
     21# For now, disable Pylint 
     22# pylint: disable-all 
     23 
    124import time 
    225from seleniumTestCase import SeleniumTestCase 
     
    1134        sel.click("createEventLink") 
    1235        sel.click("link=Lecture") 
    13         sel.wait_for_page_to_load("30000") 
     36        self.waitPageLoad(sel) 
    1437        sel.type("login", "dummyuser") 
    1538        sel.type("password", "dummyuser") 
    1639        sel.click("loginButton") 
    17         sel.wait_for_page_to_load("30000") 
     40        self.waitPageLoad(sel) 
    1841        sel.type("title", "lecture test") 
    1942        sel.click("advancedOptionsText") 
     
    2144        sel.click("advancedOptionsText") 
    2245        sel.click("ok") 
    23         sel.wait_for_page_to_load("30000") 
     46        self.waitPageLoad(sel) 
    2447 
    2548        #we set the confId, so in case the test fails, Teardown function is going to delete the conf 
    2649        SeleniumTestCase.setConfID(self, sel.get_location()) 
    2750 
    28         try: self.failUnless(sel.is_text_present("lecture test")) 
     51        try: self.failUnless(sel.is_text_present, "lecture test") 
    2952        except AssertionError, e: self.verificationErrors.append(str(e)) 
    3053        sel.click("link=Tools") 
    31         sel.wait_for_page_to_load("30000") 
     54        self.waitPageLoad(sel) 
     55 
    3256        sel.click("link=Delete") 
    33         sel.wait_for_page_to_load("30000") 
    34         try: self.failUnless(sel.is_text_present("Are you sure that you want to DELETE the conference \"lecture test\"?")) 
     57        self.waitPageLoad(sel) 
     58        try: self.failUnless(sel.is_text_present, "Are you sure that you want to DELETE the conference \"lecture test\"?") 
    3559        except AssertionError, e: self.verificationErrors.append(str(e)) 
    3660        sel.click("confirm") 
    37         sel.wait_for_page_to_load("30000") 
     61        self.waitPageLoad(sel) 
    3862 
    3963 
     
    4367        sel.click("//li[@id='createEventMenu']/span") 
    4468        sel.click("link=Create conference") 
    45         sel.wait_for_page_to_load("30000") 
     69        self.waitPageLoad(sel) 
    4670        sel.type("login", "dummyuser") 
    4771        sel.type("password", "dummyuser") 
    4872        sel.click("loginButton") 
    49         sel.wait_for_page_to_load("30000") 
     73        self.waitPageLoad(sel) 
    5074        sel.type("title", "conference test") 
    5175        sel.click("advancedOptionsText") 
    52         try: self.failUnless(sel.is_text_present("Description")) 
     76        try: self.failUnless(sel.is_text_present, "Description") 
    5377        except AssertionError, e: self.verificationErrors.append(str(e)) 
    5478        sel.click("ok") 
    55         sel.wait_for_page_to_load("30000") 
     79        self.waitPageLoad(sel) 
    5680 
    5781        #we set the confId, so in case the test fails, Teardown function is going to delete the conf 
     
    5983 
    6084        sel.click("link=Timetable") 
    61         sel.wait_for_page_to_load("30000") 
     85        self.waitPageLoad(sel) 
     86 
     87        self.waitForElement(sel, "//a[text() = 'Add new']") 
    6288        sel.click("link=Add new") 
    6389 
    6490        time.sleep(1) 
    65         self.failUnless(sel.is_text_present("Session")) 
     91        self.failUnless(sel.is_text_present, "Session") 
    6692        sel.click("link=Session") 
    6793 
    6894        time.sleep(1) 
    69         self.failUnless(sel.is_text_present("Add Session")) 
     95        self.failUnless(sel.is_text_present, "Add Session") 
    7096        sel.type("//div[@class='popupWithButtonsMainContent']//input[@type='text']", "Session One") 
    7197        sel.type("//textarea", "bla bla bla") 
     
    7399 
    74100        time.sleep(1) 
    75         self.failUnless(sel.is_text_present("Session One")) 
     101        self.failUnless(sel.is_text_present, "Session One") 
    76102 
    77103        time.sleep(1) 
     
    79105 
    80106        time.sleep(1) 
    81         self.failUnless(sel.is_text_present("View and edit this block timetable")) 
     107        self.failUnless(sel.is_text_present, "View and edit this block timetable") 
    82108 
    83109        sel.click("link=View and edit this block timetable") 
     110 
     111        self.waitForElement(sel, "//a[text() = 'Add new']") 
    84112        sel.click("link=Add new") 
    85113 
    86         self.failUnless(sel.is_text_present("Contribution")) 
     114        self.waitForElement(sel, "//a[text() = 'Contribution']") 
    87115        sel.click("link=Contribution") 
    88116 
    89         time.sleep(1) 
    90         self.failUnless(sel.is_text_present("Add Contribution")) 
     117        self.waitForAjax(sel, timeout=300000) 
     118        self.waitForElement(sel, "//div[@class='title' and contains(text(), 'Add Contribution')]") 
    91119 
    92120 
     
    94122        sel.click("//div[@class='popupButtonBar']//input[@value='Add']") 
    95123 
    96         time.sleep(5) 
    97         self.failUnless(sel.is_text_present("Contribution in Session One")) 
     124        time.sleep(2) 
     125        self.failUnless(sel.is_text_present, "Contribution in Session One") 
    98126 
    99127        sel.click("link=Go back to timetable") 
    100         self.failUnless(sel.is_text_present("Session One")) 
     128        self.failUnless(sel.is_text_present, "Session One") 
    101129 
    102130        sel.click("link=Add new") 
    103         self.failUnless(sel.is_text_present("Break")) 
     131        self.failUnless(sel.is_text_present, "Break") 
    104132        sel.click("link=Break") 
    105133        time.sleep(1) 
    106134 
    107         self.failUnless(sel.is_text_present("Add Break")) 
     135        self.failUnless(sel.is_text_present, "Add Break") 
    108136        sel.type("//div[@class='popupWithButtonsMainContent']//input[@type='text']", "Break in Contribution") 
    109137        sel.click("//input[@value='Add']") 
    110138        time.sleep(1) 
    111139 
    112         self.failUnless(sel.is_text_present("Break in Contribution")) 
     140        self.failUnless(sel.is_text_present, "Break in Contribution") 
     141 
     142 
    113143        sel.click("link=Tools") 
    114  
    115         sel.wait_for_page_to_load("30000") 
    116         sel.click("//div[@class='eventActionsToolBarButtons']//a[3]") 
    117         sel.wait_for_page_to_load("30000") 
    118  
    119         self.failUnless(sel.is_text_present("Are you sure that you want to DELETE the conference \"conference test\"?")) 
    120  
     144        self.waitPageLoad(sel) 
     145        sel.click("link=Delete") 
     146        self.waitPageLoad(sel) 
     147        try: self.failUnless(sel.is_text_present, "Are you sure that you want to DELETE the conference \"conference test\"?") 
     148        except AssertionError, e: self.verificationErrors.append(str(e)) 
    121149        sel.click("confirm") 
    122         sel.wait_for_page_to_load("30000") 
     150        self.waitPageLoad(sel) 
    123151 
    124152    def tearDown(self): 
  • indico/tests/python/functional/loop.py

    rce5cca r574b7d  
     1# -*- coding: utf-8 -*- 
     2## 
     3## 
     4## This file is part of CDS Indico. 
     5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. 
     6## 
     7## CDS Indico is free software; you can redistribute it and/or 
     8## modify it under the terms of the GNU General Public License as 
     9## published by the Free Software Foundation; either version 2 of the 
     10## License, or (at your option) any later version. 
     11## 
     12## CDS Indico is distributed in the hope that it will be useful, but 
     13## WITHOUT ANY WARRANTY; without even the implied warranty of 
     14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     15## General Public License for more details. 
     16## 
     17## You should have received a copy of the GNU General Public License 
     18## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
     19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     20 
     21# For now, disable Pylint 
     22# pylint: disable-all 
     23 
     24 
    125import sys 
     26 
    227if __name__ == '__main__': 
    328    indicoPath = '~/workspace/cds-indico' 
  • indico/tests/python/functional/seleniumTestCase.py

    r49bc7c r574b7d  
     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""" 
     23This module defines a base structure for Selenum test cases 
     24""" 
     25 
     26# Test libs 
     27from selenium import selenium 
     28import unittest, time 
     29 
     30# Indico 
     31from indico.tests import BaseTestRunner 
     32from indico.tests.runners import GridEnvironmentRunner 
     33 
    134from MaKaC.common.db import DBMgr 
     35from MaKaC.common.Configuration import Config 
    236from MaKaC.conference import ConferenceHolder 
    337from MaKaC.errors import MaKaCError 
    4 from indico.tests import BaseTestRunner 
    5 from indico.tests.runners import GridDataTestRunner 
    6 import unittest 
    7 from twill import commands as tc 
    8 from selenium import selenium 
    9 import unittest 
    10 from twill import commands as tc 
    11 from MaKaC.common.Configuration import Config 
     38 
    1239 
    1340class SeleniumTestCase(unittest.TestCase, BaseTestRunner): 
     41    """ 
     42    Base class for a selenium test case (grid or RC) 
     43    """ 
    1444 
    1545    def setUp(self): 
     
    1747        self.confId = None 
    1848        self.selenium = None 
    19         grid = GridDataTestRunner.getInstance() 
    20         if grid.isActive(): 
    21             self.selenium = selenium(grid.getUrl(), grid.getPort(), grid.getEnv(), self.getRootUrl()) 
     49 
     50        gridData = GridEnvironmentRunner.getGridData() 
     51 
     52        if gridData: 
     53            self.selenium = selenium(gridData.host, 
     54                                     gridData.port, 
     55                                     gridData.env, 
     56                                     self.getRootUrl()) 
    2257        else: 
    23             self.selenium = selenium("localhost", 4444, "*firefox", self.getRootUrl()) 
     58            self.selenium = selenium("localhost", 4444, "*firefox", 
     59                                     self.getRootUrl()) 
    2460 
    2561        self.selenium.start() 
     62        self.selenium.window_maximize() 
    2663 
    27         #Handy functions from selenium and twill you might need 
    28         #set up the time between each selenium's commands (in milliseconds) 
    29 #        self.selenium.set_speed(5000) 
    30         #convenient to set the browser in a known state 
    31 #        tc.clear_cookies() 
     64        # Handy functions from selenium and twill you might need 
     65        # set up the time between each selenium's commands (in milliseconds) 
     66        # self.selenium.set_speed(5000) 
     67 
     68        # convenient to set the browser in a known state 
     69        # from twill import commands as tc 
     70        # tc.clear_cookies() 
    3271 
    3372    def tearDown(self): 
    34         #if a confId is specified we'll try to delete the conf in case the test failed 
     73        #if a confId is specified we'll try to delete the conf 
     74        # in case the test failed 
    3575        if self.confId: 
    3676            self.deleteConference(self.confId) 
     
    4383 
    4484    def getRootUrl(self): 
     85        """ 
     86        Return root URL of Indico instance 
     87        """ 
    4588        return Config.getInstance().getBaseURL() 
    4689 
     
    5699 
    57100    def deleteConference(self, confId): 
     101        """ 
     102        Deletes a conference from the Indico DB 
     103        """ 
     104 
    58105        DBMgr.getInstance().startRequest() 
    59106 
     
    69116 
    70117        DBMgr.getInstance().endRequest() 
     118 
     119 
     120    def waitForAjax(self, sel, timeout=5000): 
     121        """ 
     122        Wait that all the AJAX calls finish 
     123        """ 
     124        time.sleep(1) 
     125        sel.wait_for_condition("selenium.browserbot.getCurrentWindow()" 
     126                               ".activeWebRequests == 0", timeout) 
     127 
     128    def waitForElement(self, sel, elem, timeout=5000): 
     129        """ 
     130        Wait for a given element to show up 
     131        """ 
     132        sel.wait_for_condition("selenium.isElementPresent(\"%s\")" % elem, timeout) 
     133 
     134    def waitPageLoad(self, sel, timeout=30000): 
     135        """ 
     136        Wait for a page to load (give it some time to load the JS too) 
     137        """ 
     138        sel.wait_for_page_to_load(timeout) 
     139        time.sleep(3) 
     140 
     141    def failUnless(self, func, *args): 
     142        """ 
     143        failUnless that supports retries 
     144        (1 per second) 
     145        """ 
     146        triesLeft = 30 
     147        exception = Exception() 
     148 
     149        while (triesLeft): 
     150            try: 
     151                unittest.TestCase.failUnless(self, func(*args)) 
     152            except AssertionError, e: 
     153                print "left %d" % triesLeft 
     154                exception = e 
     155                triesLeft -= 1 
     156                time.sleep(1) 
     157                continue 
     158            return 
     159 
     160        raise exception 
  • indico/tests/python/unit/MaKaC_tests/common_tests/configuration_test.py

    r28b84b r574b7d  
    1818## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
    1919## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     20 
     21# For now, disable Pylint 
     22# pylint: disable-all 
    2023 
    2124import unittest 
  • indico/tests/python/unit/MaKaC_tests/common_tests/contextManager_test.py

    r28b84b r574b7d  
    1818## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
    1919## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     20 
     21# For now, disable Pylint 
     22# pylint: disable-all 
     23 
    2024 
    2125import unittest 
  • indico/tests/python/unit/MaKaC_tests/common_tests/fossilize_test.py

    r28b84b r574b7d  
     1# -*- coding: utf-8 -*- 
     2## 
     3## 
     4## This file is part of CDS Indico. 
     5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. 
     6## 
     7## CDS Indico is free software; you can redistribute it and/or 
     8## modify it under the terms of the GNU General Public License as 
     9## published by the Free Software Foundation; either version 2 of the 
     10## License, or (at your option) any later version. 
     11## 
     12## CDS Indico is distributed in the hope that it will be useful, but 
     13## WITHOUT ANY WARRANTY; without even the implied warranty of 
     14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     15## General Public License for more details. 
     16## 
     17## You should have received a copy of the GNU General Public License 
     18## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
     19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     20 
     21# For now, disable Pylint 
     22# pylint: disable-all 
     23 
     24 
    125from MaKaC.common.fossilize import IFossil, Fossilizable, fossilizes, fossilize, \ 
    226    NonFossilizableException, WrongFossilTypeException, addFossil,\ 
     
    280304        s1 = SimpleClass(10, 20, 'foo') 
    281305        d1 = DerivedClass(10, 50, 'bar') 
    282         self.assertEquals(fossilize([s1, d1], {"MaKaC_tests.common_tests.testFossilize.SimpleClass": ISimpleFossil2Fossil, "MaKaC_tests.common_tests.testFossilize.DerivedClass": ISimpleFossil1Fossil}), 
     306        self.assertEquals(fossilize([s1, d1], {"indico.tests.python.unit.MaKaC_tests.common_tests.fossilize_test.SimpleClass": ISimpleFossil2Fossil, "indico.tests.python.unit.MaKaC_tests.common_tests.fossilize_test.DerivedClass": ISimpleFossil1Fossil}), 
    283307                          [s1.fossilize(ISimpleFossil2Fossil), d1.fossilize(ISimpleFossil1Fossil)]) 
    284308 
  • indico/tests/python/unit/MaKaC_tests/conference_test.py

    r28b84b r574b7d  
    2020## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2121 
     22# For now, disable Pylint 
     23# pylint: disable-all 
    2224 
    2325import unittest 
  • indico/tests/python/unit/MaKaC_tests/fileRepository_test.py

    r28b84b r574b7d  
    1919## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
    2020## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     21 
     22# For now, disable Pylint 
     23# pylint: disable-all 
    2124 
    2225""" 
  • indico/tests/python/unit/MaKaC_tests/review_test.py

    r28b84b r574b7d  
    2020## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2121 
    22 """Contains tests about some typical "call for abstracts" scenarios. 
     22# For now, disable Pylint 
     23# pylint: disable-all 
     24 
     25 
     26""" 
     27Contains tests about some typical "call for abstracts" scenarios. 
    2328""" 
    2429 
  • indico/tests/python/unit/MaKaC_tests/schedule_test.py

    r28b84b r574b7d  
    2020## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2121 
    22 """Contains tests regarding some scenarios related to schedule management. 
     22# For now, disable Pylint 
     23# pylint: disable-all 
     24 
     25 
     26""" 
     27Contains tests regarding some scenarios related to schedule management. 
    2328""" 
    2429import unittest 
  • indico/tests/python/unit/__init__.py

    rc18126 r574b7d  
    11# -*- coding: utf-8 -*- 
     2## 
     3## $Id$ 
    24## 
    35## This file is part of CDS Indico. 
     
    1820## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    1921 
    20 #Note: remove the .old to activate this package, which needs the test framework 
    21 #(it needs access to TestConfig) 
     22""" 
     23Module where the unit tests are stored 
     24""" 
  • indico/tests/python/unit/plugins_tests/Collaboration_tests/collaboration_test.py

    rce5cca r574b7d  
    1818## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
    1919## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     20 
     21# For now, disable Pylint 
     22# pylint: disable-all 
     23 
     24 
    2025from MaKaC.common.db import DBMgr 
    2126from MaKaC.conference import ConferenceHolder 
  • indico/tests/python/unit/plugins_tests/Collaboration_tests/util.py

    rce5cca r574b7d  
     1# -*- coding: utf-8 -*- 
     2## 
     3## 
     4## This file is part of CDS Indico. 
     5## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. 
     6## 
     7## CDS Indico is free software; you can redistribute it and/or 
     8## modify it under the terms of the GNU General Public License as 
     9## published by the Free Software Foundation; either version 2 of the 
     10## License, or (at your option) any later version. 
     11## 
     12## CDS Indico is distributed in the hope that it will be useful, but 
     13## WITHOUT ANY WARRANTY; without even the implied warranty of 
     14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     15## General Public License for more details. 
     16## 
     17## You should have received a copy of the GNU General Public License 
     18## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 
     19## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     20 
     21# For now, disable Pylint 
     22# pylint: disable-all 
     23 
     24 
    125from ZEO.runzeo import ZEOOptions, ZEOServer 
    226 
  • indico/tests/runners.py

    r49bc7c r574b7d  
    2424 
    2525 * UnitTestRunner 
    26  * CoverageTestRunner 
    2726 * FunctionalTestRunner 
    28  * SpecificFunctionalTestRunner 
    2927 * GridTestRunner 
    3028 * PylintTestRunner 
     
    3533 
    3634# System modules 
    37 import commands, os, signal, socket, subprocess, sys, tempfile 
     35import commands, os, socket, subprocess, tempfile, threading 
    3836 
    3937# Python stdlib 
    40 import time, re 
     38import time, urllib2 
    4139 
    4240# Test modules 
     
    4543 
    4644from indico.tests.config import TestConfig 
    47 from indico.tests.base import BaseTestRunner 
    48 from indico.tests.util import openBrowser, colored 
     45from indico.tests.base import BaseTestRunner, Option 
     46from indico.tests.util import openBrowser, relpathto 
    4947 
    5048__all__ = [ 
    5149    'UnitTestRunner', 
    52     'CoverageTestRunner', 
    5350    'FunctionalTestRunner', 
    54     'SpecificFunctionalTestRunner', 
    5551    'GridTestRunner', 
    5652    'PylintTestRunner', 
     
    5955    ] 
    6056 
     57JSTEST_CFG_FILE = "builtConf.conf" 
     58 
     59class CoverageBaseTestOption(Option): 
     60    """ 
     61    This class can be used in order to add an 
     62    optional code coverage analysis 
     63    """ 
     64 
     65    def __init__(self, value): 
     66        Option.__init__(self, value) 
     67        self.coverageDir = None 
     68 
     69    def final_message(self, __): 
     70        """ 
     71        just a short message 
     72        """ 
     73        self._info("Code coverage report generated at " 
     74                   "%s/index.html\n" % self.coverageDir) 
     75 
     76    def shouldExecute(self): 
     77        return self.value 
     78 
     79 
     80class CoveragePythonTestOption(CoverageBaseTestOption): 
     81    """ 
     82    Python Coverage Tests 
     83    """ 
     84 
     85    def __init__(self, value): 
     86        CoverageBaseTestOption.__init__(self, value) 
     87 
     88    def pre_run(self, __): 
     89        """ 
     90        starts figleaf 
     91        """ 
     92 
     93        figleaf.start() 
     94 
     95    def post_run(self, runner): 
     96        """ 
     97        stops figleaf and returns a report 
     98        """ 
     99 
     100        figleaf.stop() 
     101        coverageOutput = figleaf.get_data().gather_files() 
     102        self.coverageDir = os.path.join(runner.setupDir, 'report', 'pycoverage') 
     103 
     104        # check if there's a dir first 
     105        if not os.path.exists(self.coverageDir): 
     106            os.mkdir(self.coverageDir) 
     107 
     108        figleaf.annotate_html.report_as_html(coverageOutput, 
     109                                             self.coverageDir, [], {}) 
     110 
     111        # open a browser window with the report 
     112        openBrowser(runner.config.getBrowserPath(), os.path.join( 
     113            self.coverageDir, "index.html")) 
     114 
     115 
     116 
     117 
     118 
    61119class UnitTestRunner(BaseTestRunner): 
    62120    """ 
     
    66124    """ 
    67125 
     126    _runnerOptions = {'silent': Option, 
     127                      'coverage': CoveragePythonTestOption, 
     128                      'specify': Option} 
     129 
    68130    def _run(self): 
    69         returnString = "" 
    70  
    71         result = False 
    72  
    73         coverage = CoverageTestRunner.getInstance() 
    74         if coverage != False: 
    75             coverage.start() 
    76  
    77         self._startIOCapture() 
     131        #coverage = CoverageTestRunner.getInstance() 
     132 
     133        #if coverage: 
     134        #    coverage.start() 
    78135 
    79136        #retrieving tests from tests folder 
    80137        args = ['nose', '--nologcapture',  '--logging-clear-handlers', \ 
    81                 '--with-id', '-v', '-s', \ 
    82                 os.path.join(self.setupDir, 'python', 'unit')] 
    83         #retrieving tests from plugins folder 
    84         for folder in BaseTestRunner.walkThroughFolders(os.path.join(self.setupDir, 
    85                                                            '..', 
    86                                                            'MaKaC', 
    87                                                            'plugins'), 
    88                                               "/tests/python/unit"): 
    89             args.append(folder) 
     138                '--with-id', '-v', '-s'] 
     139 
     140        specific = self.options.valueOf('specify') 
     141 
     142        if specific: 
     143            args.append("indico.tests.python.unit.%s" % specific) 
     144        else: 
     145            args.append(os.path.join(self.setupDir, 'python', 'unit')) 
     146            # retrieving tests from plugins folder 
     147            for folder in BaseTestRunner.walkThroughFolders( 
     148                os.path.join(self.setupDir, '..', 'MaKaC', 'plugins'), 
     149                "/tests/python/unit"): 
     150                args.append(folder) 
    90151 
    91152        result = nose.run(argv = args) 
    92153 
    93         if not self.options['verbose']: 
    94             # restoring the stderr 
    95             s = self._finishIOCapture()[1] 
    96             returnString += self.writeReport("pyunit", s) 
    97  
    98         if coverage: 
    99             returnString += coverage.stop() 
    100  
    101         if result: 
    102             return returnString + "PY Unit tests succeeded\n" 
    103         else: 
    104             return returnString + \ 
    105                 "[FAIL] Unit tests - report in indico/tests/report/pyunit.txt\n" 
     154        #if coverage: 
     155        #    coverage.stop() 
     156 
     157        return result 
    106158 
    107159    def walkThroughPluginsFolders(self): 
     
    122174        return foldersArray 
    123175 
    124 class CoverageTestRunner(BaseTestRunner): 
    125     """ 
    126     Python Coverage Tests 
    127  
    128     This class is a singleton instantiate by TestRunner class and 
    129     used by Python Unit tests. 
    130     """ 
    131  
    132     __instance = None 
    133  
    134     def start(self): 
    135         """ 
    136         starts figleaf 
    137         """ 
    138         figleaf.start() 
    139  
    140     def stop(self): 
    141         """ 
    142         stops figleaf and returns a report 
    143         """ 
    144         figleaf.stop() 
    145         coverageOutput = figleaf.get_data().gather_files() 
    146         coverageDir = os.path.join(self.setupDir, 'report', 'pycoverage') 
    147  
    148         # check if there's a dir first 
    149         if not os.path.exists(coverageDir): 
    150             os.mkdir(coverageDir) 
    151  
    152         figleaf.annotate_html.report_as_html(coverageOutput, 
    153                                              coverageDir, [], {}) 
    154         return ("PY Coverage - Report generated in " 
    155                              "tests/report/pycoverage/index.html\n") 
    156  
    157     def getInstance(cls): 
    158         """ 
    159         returns a singleton instance 
    160         """ 
    161         if cls.__instance == None: 
    162             return False 
    163         return cls.__instance 
    164     getInstance = classmethod( getInstance ) 
    165  
    166     @classmethod 
    167     def instantiate(cls): 
    168         """ 
    169         create an instance of the class (singleton) 
    170         """ 
    171         cls.__instance = CoverageTestRunner() 
    172  
    173176 
    174177class FunctionalTestRunner(BaseTestRunner): 
     
    178181    Using selenium 
    179182    """ 
     183 
     184    _runnerOptions = {'silent': Option, 
     185                      'record': Option, 
     186                      'specify': Option} 
     187 
    180188 
    181189    def __init__(self, **kwargs): 
    182190        BaseTestRunner.__init__(self, **kwargs) 
    183191        self.child = None 
    184         self._record = kwargs['record'] 
    185192 
    186193    def _runSeleniumCycle(self): 
    187  
    188         returnString = '' 
    189  
    190         self._startIOCapture() 
     194        """ 
     195        Run selenium over the existing test suite (or a specific test) 
     196        """ 
    191197 
    192198        try: 
     
    195201                        ' server cannot be started.\n') 
    196202 
    197             #retrieving tests from tests folder 
    198             args = ['nose', '--nologcapture', '--logging-clear-handlers', '-v', 
    199                     os.path.join(self.setupDir, 'python', 'functional')] 
    200  
    201             #retrieving tests from plugins folder 
    202             for folder in BaseTestRunner.walkThroughFolders( 
    203                 os.path.join(self.setupDir, '..', 'MaKaC', 'plugins'), 
    204                 "/tests/python/functional"): 
    205                 args.append(folder) 
     203            args = ['nose', '--nologcapture', '--logging-clear-handlers', 
     204                    '-v'] 
     205 
     206            specific = self.options.valueOf('specify') 
     207 
     208            # if a particular test was specified 
     209            if specific: 
     210                args.append("indico.tests.python.functional.%s" % specific) 
     211            else: 
     212                args.append(os.path.join(self.setupDir, 'python', 'functional')) 
     213                # retrieving tests from plugins folder 
     214                for folder in BaseTestRunner.walkThroughFolders( 
     215                    os.path.join(self.setupDir, '..', 'MaKaC', 'plugins'), 
     216                    "/tests/python/functional"): 
     217                    args.append(folder) 
    206218 
    207219            result = nose.run(argv = args) 
     
    212224            self._stopSeleniumServer() 
    213225 
    214             #restoring the stderr 
    215             sys.stderr = sys.__stderr__ 
    216  
    217         s = self._finishIOCapture()[1] 
    218         returnString += self.writeReport("pyfunctional", s) 
    219  
    220         if result: 
    221             report = returnString + "PY Functional tests succeeded\n" 
     226        return result 
     227 
     228    def _run(self): 
     229 
     230        if self.options.valueOf('record'): 
     231            raw_input("Press [ENTER] to finish recording... ") 
     232            result = False 
    222233        else: 
    223             report = returnString + ("[FAIL] Functional tests - report in" 
    224                     " tests/report/pyfunctional.txt\n") 
    225  
    226         return report 
    227  
    228     def _run(self): 
    229         returnString = "" 
    230  
    231         if self._record: 
    232             raw_input("Press [ENTER] to finish recording... ") 
    233             report = "" 
    234         else: 
    235             report = self._runSeleniumCycle() 
    236  
    237         return report 
     234            result = self._runSeleniumCycle() 
     235 
     236        return result 
    238237 
    239238    def walkThroughPluginsFolders(self): 
     
    257256        started = True 
    258257 
    259         self.info("Starting Selenium Server") 
     258        self._info("Starting Selenium Server") 
    260259 
    261260        try: 
     
    274273            return "[ERR] Please specify a SeleniumFilename in tests.conf\n" 
    275274 
    276         self.info("Starting Selenium RC") 
     275        self._info("Starting Selenium RC") 
    277276 
    278277        sel = selenium("localhost", 4444, "*firefox", "http://www.cern.ch/") 
     
    301300 
    302301 
    303 class SpecificFunctionalTestRunner(FunctionalTestRunner): 
    304     """ 
    305     Specific Functional Test 
    306     """ 
    307  
    308     def __init__(self, specifyArg, **kwargs): 
    309         FunctionalTestRunner.__init__(self) 
    310         self.specify = specifyArg 
    311  
    312     def _run(self): 
    313         #if specified path does not contained unit, we are probably dealing 
    314         #with functional tests 
    315  
    316         if self.specify.find('unit/') < 0: 
    317             if not self.startSeleniumServer(): 
    318                 return ('[ERR] Could not start functional tests because selenium' 
    319                         ' server cannot be started.\n') 
    320             try: 
    321                 #running the test and ouputing in the console 
    322                 result = nose.run(argv=['nose', '-v', os.path.join(self.setupDir, 
    323                                                                    '..', 
    324                                                                    self.specify)]) 
    325             finally: 
    326                 self.stopSeleniumServer() 
     302class GridEnvironmentRunner(threading.Thread): 
     303    """ 
     304    Rspresents a specific grid environment (FF Linux, IE Windows, etc...) 
     305    """ 
     306 
     307    def __init__(self, gridData, setupDir, resultEntry): 
     308        threading.Thread.__init__(self) 
     309        self.setupDir = setupDir 
     310        self.gridData = gridData 
     311        self.result = None 
     312        self.resultEntry = resultEntry 
     313 
     314    def run(self): 
     315 
     316        self.result = nose.run(argv=['nose', '--nologcapture', '--nocapture', 
     317                                     '--logging-clear-handlers', '-v', 
     318                                     os.path.join(self.setupDir, 'python', 
     319                                                  'functional')]) 
     320 
     321        self.resultEntry['success'] = self.result 
     322 
     323    def stop(self): 
     324        """ 
     325        Stop the GridEnvironmentRunner, by joining its thread 
     326        """ 
     327 
     328        self.join() 
     329 
     330        if self.result: 
     331            return True 
    327332        else: 
    328             #running the test and ouputing in the console 
    329             result = nose.run(argv=['nose', '-v', os.path.join(self.setupDir, 
    330                                                            '..', 
    331                                                            self.specify)]) 
    332  
    333         if result: 
    334             return "Specified Test - Succeeded\n" 
     333            return False 
     334 
     335    @classmethod 
     336    def getGridData(cls): 
     337        """ 
     338        returns the data that is stored by the thread, if any 
     339        """ 
     340 
     341        thread = threading.currentThread() 
     342 
     343        if hasattr(thread, 'gridData'): 
     344            return thread.gridData 
    335345        else: 
    336             return "[FAIL] Specified Test - read output from console\n" 
     346            return None 
    337347 
    338348class GridTestRunner(BaseTestRunner): 
     
    340350    Selenium Grid Tests 
    341351    """ 
     352 
     353    _runnerOptions = {'silent': Option, 
     354                      'parallel': Option, 
     355                      'specify': Option } 
    342356 
    343357    def __init__(self, **kwargs): 
     
    348362            testConf = TestConfig.getInstance() 
    349363            self.hubEnv = testConf.getHubEnv() 
    350             self.gridData = GridDataTestRunner.getInstance() 
    351             self.gridData.setUrl(testConf.getHubURL()) 
    352             self.gridData.setPort(testConf.getHubPort()) 
    353             self.gridData.setActive(False) 
    354364            self.configExists = True 
    355365        except KeyError: 
    356366            self.configExists = False 
    357367 
     368        self.gridData = None 
     369        specifiedEnv = self.options.valueOf('specify') 
     370 
     371        if specifiedEnv: 
     372            self.hubEnv = [specifiedEnv] 
     373 
     374    def _runSerial(self, resultDict, testConf): 
     375        """ 
     376        Run the tests one after the other 
     377        """ 
     378 
     379        for envName in self.hubEnv: 
     380            envRunner = self._runEnv(envName, resultDict, testConf) 
     381            envRunner.stop() 
     382 
     383 
     384    def _runParallel(self, resultDict, testConf): 
     385        """ 
     386        Run all the tests at the same time 
     387        """ 
     388 
     389        # launch every environment 
     390        for envName in self.hubEnv: 
     391            self._runEnv(envName, resultDict, testConf) 
     392 
     393        # give it some time to start up 
     394        time.sleep(1) 
     395 
     396        # wait so that there are no more runner threads executing 
     397        while(len(list(thread for thread in threading.enumerate() 
     398                       if isinstance(thread, GridEnvironmentRunner))) > 0): 
     399            time.sleep(1) 
     400 
     401 
     402    def _runEnv(self, envName, resultDict, testConf): 
     403        """ 
     404        Run a specific test environment, spawning a GridEnvironmentRunner 
     405        """ 
     406        self._info("Starting env %s" % envName) 
     407 
     408        self.gridData = GridData(testConf.getHubURL(), 
     409                                 testConf.getHubPort(), 
     410                                 envName, 
     411                                 active = True) 
     412 
     413        resultEntry = resultDict[envName] = {} 
     414 
     415        envRunner = GridEnvironmentRunner(self.gridData, self.setupDir, resultEntry) 
     416        envRunner.start() 
     417 
     418        return envRunner 
     419 
     420 
    358421    def _run(self): 
     422 
     423        resultDict = {} 
     424        result = True 
    359425 
    360426        if not self.configExists: 
     
    362428 
    363429        try: 
    364             try: 
    365                 self.gridData.setActive(True) 
    366  
    367                 #Checking if hub is online 
    368                 sel = selenium(self.gridData.getUrl(), self.gridData.getPort(), 
    369                                self.hubEnv[0], "http://www.cern.ch/") 
    370  
    371                 signal.signal(signal.SIGALRM, raiseTimeout) 
    372                 signal.alarm(15) 
    373                 sel.start() 
    374                 sel.open("/") 
    375                 sel.stop() 
    376                 #disable the alarm signal 
    377                 signal.alarm(0) 
    378  
    379                 self._startIOCapture() 
    380  
    381                 returnString = "" 
    382                 for env in self.hubEnv: 
    383                     self.gridData.setEnv(env) 
    384                     sys.stderr.write('\n~ %s ~\n' % env) 
    385                     result = nose.run(argv=['nose', '--nologcapture', 
    386                                             '--logging-clear-handlers', '-v', 
    387                                             os.path.join(self.setupDir, 
    388                                                          'python', 
    389                                                          'functional')]) 
    390                     if result: 
    391                         returnString += "PY Functional (%s) tests succeeded\n" % env 
    392                     else: 
    393                         returnString += ("[FAIL] Functional (%s) tests - report in" 
    394                                 " tests/report/pygrid.txt\n") % env 
    395  
    396                 s = self._finishIOCapture()[1] 
    397  
    398                 returnString += self.writeReport("pygrid", s) 
    399             except socket.error: 
    400                 return ("[ERR] Selenium Grid - Connection refused, check your " 
    401                         "hub's settings (%s:%s)") % \ 
    402                         (self.gridData.getUrl(), self.gridData.getPort()) 
    403             except TimeoutException, e: 
    404                 return "[ERR] Selenium Grid - Hub is probably down " \ 
    405                        "(%s:%s) (%s)\n" % \ 
    406                        (self.gridData.getUrl(), self.gridData.getPort(), e) 
    407         finally: 
    408             #disable alarm 
    409             signal.alarm(0) 
    410  
    411         return returnString 
    412  
    413 class GridDataTestRunner(BaseTestRunner): 
     430            testConf = TestConfig.getInstance() 
     431 
     432            # Ping server, just to know it is alive 
     433            urllib2.urlopen("http://%s:%s/heartbeat" % (testConf.getHubURL(), 
     434                                                        testConf.getHubPort())) 
     435 
     436            if self.options.valueOf('parallel'): 
     437                self._runParallel(resultDict, testConf) 
     438            else: 
     439                self._runSerial(resultDict, testConf) 
     440 
     441            for name, resultEntry in resultDict.iteritems(): 
     442                if resultEntry['success']: 
     443                    resultStr = 'OK' 
     444                else: 
     445                    resultStr = 'FAIL' 
     446                    result = False 
     447                print "%s\t %s" % (name, resultStr) 
     448 
     449        except socket.error: 
     450            self._error("[ERR] Selenium Grid - Connection refused, check your " 
     451                        "hub's settings (%s:%s)" % \ 
     452                        (testConf.getHubURL(), testConf.getHubPort())) 
     453            return False 
     454        except urllib2.URLError, e: 
     455            self._error("[ERR] Selenium Grid - Hub is probably down " \ 
     456                        "(%s:%s) (%s)\n" % \ 
     457                        (testConf.getHubURL(), testConf.getHubPort(), e)) 
     458            return False 
     459        except Exception, e: 
     460            self._error(e) 
     461            return False 
     462 
     463        return result 
     464 
     465class GridData(object): 
    414466    """ 
    415467    Provides informations for selenium grid, data are set from Class Grid 
     
    418470    """ 
    419471 
    420     __instance = None 
     472    def __init__(self, host, port, env, active = False): 
     473        self.active = active 
     474        self.host = host 
     475        self.port = port 
     476        self.env = env 
     477 
     478 
     479class HTMLOption(Option): 
     480    """ 
     481    Represents the option that allows HTML reports to be generated 
     482    instead of console output 
     483    """ 
     484 
     485    def __init__(self, value): 
     486 
     487        Option.__init__(self, value) 
     488        self.tmpFile = None 
     489 
     490    def prepare_outstream(self, runner): 
     491        """ 
     492        Forward the output to either a file or the process output 
     493        """ 
     494 
     495        if self.value: 
     496            __, filePath = tempfile.mkstemp() 
     497            self.tmpFile = open(filePath, 'w+b') 
     498            runner.outStream = self.tmpFile 
     499        else: 
     500            # for regular text, just use a pipe 
     501            runner.outStream = subprocess.PIPE 
     502 
     503    def write_report(self, runner, fileName, content): 
     504        """ 
     505        Open the browser or write an actual report, depending on the state 
     506        of the option 
     507        """ 
     508        if self.value: 
     509            self.tmpFile.close() 
     510            # open a browser window with the report 
     511            openBrowser(runner.config.getBrowserPath(), self.tmpFile.name) 
     512        else: 
     513            # for non-html output, use the normal mechanisms 
     514            runner.writeNormalReport(fileName, content) 
     515 
     516 
     517class PylintTestRunner(BaseTestRunner): 
     518    """ 
     519    Pylint 
     520    """ 
     521 
     522    _runnerOptions = {'silent': Option, 
     523                      'html': HTMLOption} 
     524 
    421525    def __init__(self, **kwargs): 
     526 
    422527        BaseTestRunner.__init__(self, **kwargs) 
    423         self.active = None 
    424         self.url = None 
    425         self.port = None 
    426         self.active = None 
    427         self.currentEnv = None 
    428  
    429     def isActive(self): 
    430         """ 
    431         returns True if the grid is active, False otherwise 
    432         """ 
    433         return self.active 
    434  
    435     def getUrl(self): 
    436         """ 
    437         returns the hub URL 
    438         """ 
    439         return self.url 
    440  
    441     def getPort(self): 
    442         """ 
    443         returns the hub port 
    444         """ 
    445         return self.port 
    446  
    447     def getEnv(self): 
    448         """ 
    449         returns the current running environment 
    450         """ 
    451         return self.currentEnv 
    452  
    453     def setActive(self, active): 
    454         """ 
    455         sets the active status for the grid 
    456         """ 
    457         self.active = active 
    458  
    459     def setUrl(self, url): 
    460         """ 
    461         sets the hub url 
    462         """ 
    463         self.url = url 
    464  
    465     def setPort(self, port): 
    466         """ 
    467         sets the hub port 
    468         """ 
    469         self.port = port 
    470  
    471     def setEnv(self, env): 
    472         """ 
    473         sets the current running environment 
    474         """ 
    475         self.currentEnv = env 
    476  
    477     @classmethod 
    478     def getInstance(cls): 
    479         """ 
    480         gets a class instance (singleton) 
    481         """ 
    482         if cls.__instance == None: 
    483             cls.__instance = GridDataTestRunner() 
    484         return cls.__instance 
    485  
    486  
    487 class PylintTestRunner(BaseTestRunner): 
    488     """ 
    489     Pylint 
    490     """ 
     528        self.outStream = None 
    491529 
    492530    def _run(self): 
    493531 
    494         htmlReport = self.options['html'] 
    495         returnString = "" 
    496532        fileList = self.config.getPylintFiles() 
    497  
    498         self._startIOCapture() 
    499533 
    500534        try: 
     
    504538                                                  os.environ.get('PYTHONPATH','')) 
    505539 
     540            # Prepare the args for Pylint 
    506541            args = ["pylint", "--rcfile=%s" % 
    507542                    os.path.join(self.setupDir, 
     
    511546                    ] + fileList 
    512547 
    513             if htmlReport: 
     548            if self.options.valueOf('html'): 
    514549                args += ['-f', 'html'] 
     550 
     551            # will set self.outStream 
     552            self._callOptions('prepare_outstream') 
    515553 
    516554            pylintProcess = subprocess.Popen( 
    517555                args, 
    518                 stdout = subprocess.PIPE, 
     556                stdout = self.outStream, 
    519557                stderr = subprocess.PIPE) 
    520558 
    521             self._redirectPipeToStdout(pylintProcess.stdout) 
     559            # for regular aoutput, redirect the out pipe to stdout 
     560            if not self.options.valueOf('html'): 
     561                self._redirectPipeToStdout(pylintProcess.stdout) 
     562 
     563            # stderr always goes to the same place 
     564            self._redirectPipeToStdout(pylintProcess.stderr) 
     565 
     566            # wait pylint to finish 
     567            pylintProcess.wait() 
     568 
    522569        except OSError, e: 
    523             self._finishIOCapture() 
    524             return ("[ERR] Could not start Source Analysis - " 
    525                     "command \"pylint\" needs to be in your PATH. (%s)\n" % e) 
    526  
    527         statusOutput = self._finishIOCapture() 
    528  
    529         if htmlReport: 
    530             __, filePath = tempfile.mkstemp() 
    531             tmpFile = open(filePath, 'w+b') 
    532             tmpFile.write(statusOutput[0]) 
    533             tmpFile.close() 
    534  
     570            self._error("[ERR] Could not start Source Analysis - " 
     571                        "command \"pylint\" needs to be in your PATH. (%s)\n" % e) 
     572            return False 
     573 
     574        return True 
     575 
     576    def _writeReport(self, fileName, content): 
     577 
     578        # overloaded just to handle the case of HTML reports 
     579        self._callOptions('write_report', fileName, content) 
     580 
     581    def writeNormalReport(self, fileName, content): 
     582        """ 
     583        Just call the parent report writing method 
     584        (used from HTMLOption) 
     585        """ 
     586        BaseTestRunner._writeReport(self, fileName, content) 
     587 
     588 
     589class CoverageJSTestOption(CoverageBaseTestOption): 
     590    """ 
     591    Python Coverage Tests 
     592    """ 
     593 
     594    def __init__(self, value): 
     595        CoverageBaseTestOption.__init__(self, value) 
     596 
     597    def post_run(self, runner): 
     598        """ 
     599        Creates a coverage report in HTML 
     600        """ 
     601 
     602        #generate html for coverage 
     603 
     604        reportPath = os.path.join(runner.setupDir, 'report', 'jscoverage') 
     605        genOutput = commands.getstatusoutput( 
     606            "genhtml -o %s %s" % (reportPath, 
     607                                  os.path.join(reportPath, 
     608                                               '%s-coverage.dat' % 
     609                                               JSTEST_CFG_FILE))) 
     610 
     611        self.coverageDir = reportPath 
     612 
     613        if genOutput[1].find("genhtml") > -1: 
     614            BaseTestRunner._error("JS Unit Tests - html coverage " 
     615                                  "generation failed, genhtml needs to be " 
     616                                  "in your PATH. (%s)\n" % genOutput[1]) 
     617        else: 
     618            BaseTestRunner._info("JS Coverage - report generated\n") 
    535619            # open a browser window with the report 
    536             openBrowser(self.config.getBrowserPath(), filePath) 
    537             return "" 
    538         else: 
    539             returnString += self.writeReport("pylint", statusOutput[0]) 
    540             return returnString + "PY Lint - report in indico/tests/report/pylint.txt\n" 
     620            openBrowser(runner.config.getBrowserPath(), os.path.join( 
     621                reportPath, "index.html")) 
    541622 
    542623 
     
    547628    Based on JSUnit 
    548629    """ 
     630 
     631    _runnerOptions = {'silent': Option, 
     632                      'coverage': CoverageJSTestOption, 
     633                      'specify': Option} 
    549634 
    550635    def __init__(self, **kwargs): 
    551636        BaseTestRunner.__init__(self, **kwargs) 
    552         self.coverage = self.options['coverage'] 
    553         self.specify = self.options['specify'] 
     637        self.coverage = self.options.valueOf('coverage') 
     638        self.specify = self.options.valueOf('specify') 
    554639 
    555640    def _run(self): 
    556641 
    557642        #conf file used at run time 
    558         confFile = ("builtConf.conf") 
    559         #path relative to the jar file 
    560         coveragePath = os.path.join('..', '..', 'report', 'jscoverage') 
    561643 
    562644        try: 
     
    578660            #constructing conf file depending on installed plugins and 
    579661            #coverage activation 
    580             success = self.buildConfFile(confFile, self.coverage) 
    581             if not (success == ""): 
    582                 return success 
     662 
     663            success = self.buildConfFile(JSTEST_CFG_FILE, self.coverage) 
     664 
     665            if success != "": 
     666                self._error(success) 
     667                return False 
    583668 
    584669            #switching directory to run the tests 
     
    594679                                             (TestConfig.getInstance(). 
    595680                                              getJSUnitFilename(), 
    596                                               confFile)) 
     681                                              JSTEST_CFG_FILE)) 
    597682                if jsDryRun[1].startswith("No browsers were captured"): 
    598683                    print ("Js-test-driver server has not started yet. " 
     
    615700            command = ("java -jar %s " 
    616701                            "--config %s " 
     702                            "--verbose " 
    617703                            "--tests %s ") % \ 
    618704                            (TestConfig.getInstance().getJSUnitFilename(), 
    619                              confFile, 
     705                             JSTEST_CFG_FILE, 
    620706                             toTest) 
     707 
    621708            if self.coverage: 
    622                 command += "--testOutput %s" % coveragePath 
     709                # path relative to the jar file 
     710                command += "--testOutput %s" % \ 
     711                           os.path.join('..', '..', 'report', 'jscoverage') 
    623712 
    624713            #running tests 
    625714            jsTest = commands.getoutput(command) 
    626715 
    627             coverageReport = "" 
    628             if self.coverage: 
    629                 #generate html for coverage 
    630                 genOutput = commands.getstatusoutput("genhtml -o %s %s" % 
    631                                                     (os.path.join('..', 
    632                                                                 '..', 
    633                                                                 'report', 
    634                                                                 'jscoverage'), 
    635                                                     os.path.join('..', 
    636                                                                  '..', 
    637                                                                  'report', 
    638                                                                  'jscoverage', 
    639                                            '%s-coverage.dat' % confFile))) 
    640  
    641                 if genOutput[1].find("genhtml") > -1: 
    642                     coverageReport = ("[ERR] JS Unit Tests - html coverage " 
    643                                       "generation failed, genhtml needs to be " 
    644                                       "in your PATH. (%s)\n" % genOutput[1]) 
    645                 else: 
    646                     coverageReport = ("JS Coverage - generated in " 
    647                                      "tests/report/jscoverage/index.html\n") 
     716            print jsTest 
    648717 
    649718            #delete built conf file 
    650             os.unlink(confFile) 
     719            os.unlink(JSTEST_CFG_FILE) 
    651720 
    652721            #restoring directory 
    653722            os.chdir(self.setupDir) 
    654723 
    655             report = "" 
    656             if self.specify: 
    657                 #ouputing directly in the console 
    658                 print jsTest 
    659                 report = "JS Unit Tests - Output in console\n" 
    660             else: 
    661                 report += self.writeReport("jsunit", jsTest) 
    662  
    663                 #check if all tests succedded 
    664                 successRegexp = re.compile('(.|\n)*\nTotal\s[0-9]+\stests' \ 
    665                                            '\s\(Passed:\s[0-9]+;\sFails:\s0;' \ 
    666                                            '\sErrors:\s0\).*\n(.|\n)*') 
    667                 success = successRegexp.match(jsTest) 
    668                 if not success: 
    669                     report += ("[FAIL] JS Unit Tests - report in " 
    670                           "tests/report/jsunit.txt\n") 
    671                 else: 
    672                     report += ("JS Unit tests succeeded\n") 
    673724        except OSError, e: 
    674725            return ("[ERR] Could not start js-test-driver server - command " 
     
    679730        #stopping the server 
    680731        server.kill() 
    681         return coverageReport + report 
     732        return True 
    682733 
    683734    def buildConfFile(self, confFilePath, coverage): 
    684735        """ 
    685         Builds a jslint config file 
    686         """ 
    687         confTemplatePath = os.path.join(self.setupDir, 
     736        Builds a driver config file 
     737        """ 
     738        confTemplateDir = os.path.join(self.setupDir, 
    688739                                        'javascript', 
    689                                         'unit', 
    690                                         'confTemplate.conf') 
    691  
    692         relativeTestsFolder = os.path.join("tests") 
    693         absoluteTestsFolder = os.path.join(self.setupDir, 
     740                                        'unit') 
     741        confTemplatePath = os.path.join(confTemplateDir, 'confTemplate.conf') 
     742 
     743        absoluteTestsDir = os.path.join(self.setupDir, 
    694744                                           "javascript", 
    695745                                           "unit", 
    696746                                           "tests") 
    697747 
    698         relativePluginsFolder = os.path.join("..", "indico", "MaKaC", "plugins") 
    699         absolutePluginsFolder = os.path.join(self.setupDir, 
     748        absolutePluginDir = os.path.join(self.setupDir, 
     749                                            "..", 
    700750                                            "..", 
    701751                                            "indico", 
    702752                                            "MaKaC", 
    703753                                            "plugins") 
     754 
    704755        try: 
    705756            #lines needed to activate coverage plugin 
     
    708759    jar: \"plugins/%s\" 
    709760    module: \"com.google.jstestdriver.coverage.CoverageModule\"""" % \ 
    710         TestConfig.getInstance().getJscoverageFilename() 
     761        TestConfig.getInstance().getJSCoverageFilename() 
    711762        except KeyError: 
    712             return "[ERR] Please, specify a JscoverageFilename in tests.conf\n" 
     763            return "Please, specify a JSCoverageFilename in tests.conf\n" 
    713764 
    714765 
     
    720771 
    721772            #adding tests files from tests folder 
    722             for root, __, files in os.walk(absoluteTestsFolder): 
     773            for root, __, files in os.walk(absoluteTestsDir): 
    723774                for name in files: 
    724775                    if name.endswith(".js"): 
    725776                        absoluteFilePath = os.path.join(root, name) 
    726                         splitPath = absoluteFilePath.split(relativeTestsFolder) 
    727                         relativeFilePath = relativeTestsFolder + splitPath[2] 
     777                        relativeFilePath = relpathto(confTemplateDir, 
     778                                                     absoluteFilePath) 
    728779 
    729780                        confTemplate += "\n  - %s" % os.path.join(relativeFilePath) 
     
    731782 
    732783            #adding plugins test files 
    733             for root, __, files in os.walk(absolutePluginsFolder): 
     784            for root, __, files in os.walk(absolutePluginDir): 
    734785                for name in files: 
    735786                    if name.endswith(".js") and \ 
    736787                                          root.find("/tests/javascript/unit") > 0: 
    737788                        absoluteFilePath = os.path.join(root, name) 
    738                         splitPath = absoluteFilePath.split(relativePluginsFolder) 
    739                         relativeFilePath = relativePluginsFolder + splitPath[1] 
     789                        relativeFilePath = relpathto(confTemplateDir, 
     790                                                     absoluteFilePath) 
    740791 
    741792                        confTemplate += "\n  - %s" % os.path.join('..', 
     
    747798                confTemplate += coverageConf 
    748799 
    749             #writing the compelete configuration in a file 
     800            #writing the complete configuration in a file 
    750801            confFile = open(os.path.join(self.setupDir, 'javascript', 'unit', 
    751802                                         confFilePath), 'w') 
     
    755806            return "" 
    756807        except IOError, e: 
    757             return "[ERR] JS Unit Tests - Could not open a file. (%s)" % e 
     808            return "JS Unit Tests - Could not open a file. (%s)" % e 
    758809 
    759810class JSLintTestRunner(BaseTestRunner): 
     
    763814 
    764815    def _run(self): 
    765         returnString = "" 
    766  
    767         #Folders which are not going to be scanned. 
    768         #Files are going to be find recursively in the other folders 
     816 
     817        # Folders which are not going to be scanned. 
     818        # Files are going to be find recursively in the other folders 
    769819        import sets 
    770820        blackList = sets.Set(['pack', 'Loader.js', 'Common', 'i18n']) 
    771  
    772         outputString = "" 
    773821 
    774822        #checking if rhino is accessible 
     
    780828        #constructing a list of folders to scan 
    781829        folderNames = [] 
    782         fileList  = os.listdir(os.path.join(self.setupDir, 
    783                                         '..', 
    784                                         'indico', 
    785                                         'htdocs', 
    786                                         'js', 
    787                                         'indico')) 
     830 
     831        indicoDir = os.path.join(self.setupDir, '..', '..', 'indico') 
     832 
     833        fileList  = os.listdir(os.path.join(indicoDir, 
     834                                            'htdocs', 
     835                                            'js', 
     836                                            'indico')) 
    788837        for name in fileList: 
    789838            if not (name in blackList): 
     
    792841        #Scanning Indico core 
    793842        for folderName in folderNames: 
    794             outputString += self.runJSLint( 
    795                 os.path.join( 
    796                     self.setupDir, '..', 'indico', 'htdocs', 
    797                     'js', 'indico'), 
     843            self.runJSLint( 
     844                os.path.join(indicoDir, 'htdocs', 'js', 'indico'), 
    798845                folderName) 
    799846 
    800847        #Scanning plugins js files 
    801         outputString += self.runJSLint( 
    802             os.path.join( 
    803                 self.setupDir,'..', 'indico', 'MaKaC', 'plugins')) 
    804  
    805         returnString += self.writeReport("jslint", outputString) 
    806         return returnString + "JS Lint - report in tests/report/jslint.txt\n" 
     848        return self.runJSLint( 
     849            os.path.join(indicoDir, 'MaKaC', 'plugins')) 
     850 
    807851 
    808852    def runJSLint(self, path, folderRestriction=''): 
     
    810854        runs the actual JSLint command 
    811855        """ 
    812         returnString = "" 
     856 
    813857        for root, __, files in os.walk(os.path.join(self.setupDir, 
    814858                                                    path, 
     
    817861                if name.endswith(".js"): 
    818862                    filename = os.path.join(root, name) 
    819                     returnString += ("\n================== Scanning %s " 
    820                                      "==================\n") % filename 
     863                    self._info("Scanning %s" % filename) 
    821864                    output = commands.getstatusoutput("rhino %s %s" % 
    822865                                                      (os.path.join( 
     
    825868                                                                'jslint', 
    826869                                                                'jslint.js'), 
    827                                                                 filename)) 
    828                     returnString += output[1] 
    829         return returnString 
    830  
    831 class TimeoutException(Exception): 
    832     """SIGALARM was sent to the process""" 
    833     pass 
    834  
    835 def raiseTimeout(__, ___): 
    836     """ 
    837     handler for the timeout signal 
    838     """ 
    839     raise TimeoutException("15sec Timeout") 
     870                                                       filename)) 
     871                    print output[1] 
     872 
     873                    if output[0] != 0: 
     874                        return False 
     875        return True 
     876 
  • indico/tests/tests.conf.sample

    r49bc7c r574b7d  
    3232                        "indico.tests"] 
    3333 
    34 JSUnitURL          = "http://js-test-driver.googlecode.com/files/JsTestDriver-1.2.jar" 
    35 JSUnitFilename     = "JsTestDriver-1.2.jar" 
     34JSUnitURL          = "http://js-test-driver.googlecode.com/files/JsTestDriver-1.2.2.jar" 
     35JSUnitFilename     = "JsTestDriver-1.2.2.jar" 
    3636 
    37 JscoverageURL      = "http://js-test-driver.googlecode.com/files/coverage-1.2.jar" 
    38 JscoverageFilename = "coverage-1.2.jar" 
     37JSCoverageURL      = "http://js-test-driver.googlecode.com/files/coverage-1.2.2.jar" 
     38JSCoverageFilename = "coverage-1.2.2.jar" 
    3939 
    40 SeleniumURL        = "http://release.seleniumhq.org/selenium-remote-control/1.0.1/selenium-remote-control-1.0.1-dist.zip" 
    41 SeleniumInZipPath  = "selenium-remote-control-1.0.1/selenium-server-1.0.1/selenium-server.jar" 
    42 SeleniumZipname    = "selenium-remote-control-1.0.1-dist.zip" 
     40SeleniumURL        = "http://selenium.googlecode.com/files/selenium-remote-control-1.0.3.zip" 
     41SeleniumInZipPath  = "selenium-server-1.0.3/selenium-server.jar" 
     42SeleniumZipname    = "selenium-remote-control-1.0.3.zip" 
    4343SeleniumFilename   = "selenium-server.jar" 
    44  
    4544 
    4645#------------------------------------------------------------------------------ 
     
    5251                  'Firefox on Linux', 
    5352                  'IE on Windows'] 
     53 
     54#------------------------------------------------------------------------------ 
     55# Plugins 
     56#------------------------------------------------------------------------------ 
     57 
     58CollaborationOptions = { 
     59    'Vidyo': { 
     60        'indicoUsername': 'jdoe', 
     61        'indicoPassword': 'jdoe' 
     62        } 
     63    } 
  • indico/tests/util.py

    r49bc7c r574b7d  
    5252    Wrapper for StringIO that writes to an output stream as well 
    5353    """ 
    54     def __init__(self, out): 
     54    def __init__(self, out, targetStream = None): 
    5555        self.__outStream =  out 
     56        self.__targetStream = targetStream 
    5657        StringIO.__init__(self) 
    5758 
    58     def write(self, string): 
    59         self.__outStream.write(string) 
    60         StringIO.write(self, string) 
     59    def write(self, string, echo=True): 
     60 
     61        if echo: 
     62            self.__outStream.write(string) 
     63        if self.__targetStream: 
     64            self.__targetStream.write(string, echo=False) 
     65        else: 
     66            StringIO.write(self, string) 
    6167 
    6268    def read(self, n=-1): 
    6369        self.seek(0) 
    64         self.__outStream.write(StringIO.read(self, n=n)) 
     70        self.__outStream.write(StringIO.read(self.__targetStream or self, n=n)) 
     71 
    6572 
    6673def openBrowser(browserPath, filePath): 
     
    6976    """ 
    7077    os.system("%s %s" % (browserPath, filePath)) 
     78 
     79 
     80### 
     81# path manipulation functions 
     82# adapted from path.py (Jason Orendorff <jason at jorendorff com>) 
     83# 
     84# (Public Domain code) 
     85### 
     86 
     87def splitall(loc): 
     88    """ 
     89    Return a list of the path components in this path. 
     90 
     91    The first item in the list will be a path.  Its value will be 
     92    either os.curdir, os.pardir, empty, or the root directory of 
     93    this path (for example, '/' or 'C:\\').  The other items in 
     94    the list will be strings. 
     95 
     96    path.path.joinpath(*result) will yield the original path. 
     97    """ 
     98 
     99    parts = [] 
     100    while loc != os.curdir and loc != os.pardir: 
     101        prev = loc 
     102        loc, child = os.path.split(prev) 
     103        if loc == prev: 
     104            break 
     105        parts.append(child) 
     106    parts.append(loc) 
     107    parts.reverse() 
     108    return parts 
     109 
     110 
     111def relpathto(origin, dest): 
     112    """ 
     113    Return a relative path from self to dest. 
     114 
     115    If there is no relative path from self to dest, for example if 
     116    they reside on different drives in Windows, then this returns 
     117    dest.abspath(). 
     118    """ 
     119 
     120    orig_list = splitall(os.path.normcase(origin)) 
     121    # Don't normcase dest!  We want to preserve the case. 
     122    dest_list = splitall(dest) 
     123 
     124    if orig_list[0] != os.path.normcase(dest_list[0]): 
     125        # Can't get here from there. 
     126        return dest 
     127 
     128    # Find the location where the two paths start to differ. 
     129    i = 0 
     130    for start_seg, dest_seg in zip(orig_list, dest_list): 
     131        if start_seg != os.path.normcase(dest_seg): 
     132            break 
     133        i += 1 
     134 
     135    # Now i is the point where the two paths diverge. 
     136    # Need a certain number of "os.pardir"s to work up 
     137    # from the origin to the point of divergence. 
     138    segments = [os.pardir] * (len(orig_list) - i) 
     139    # Need to add the diverging part of dest_list. 
     140    segments += dest_list[i:] 
     141    if len(segments) == 0: 
     142        # If they happen to be identical, use os.curdir. 
     143        relpath = os.curdir 
     144    else: 
     145        relpath = os.path.join(*segments) 
     146    return relpath 
     147 
     148### END ### 
    71149 
    72150# pylint: disable-msg=W0611 
  • setup.py

    r49bc7c r574b7d  
    316316                    ('html', None, "Make an HTML report (when possible)"), 
    317317                    ('record', None, "Record tests (for --functional)"), 
    318                     ('full-output', None, "Write the results to the console, in addition to the log file")] 
     318                    ('parallel', None, "Parallel test execution (for --functional)"), 
     319                    ('silent', None, "Don't output anything in the console, just generate the report")] 
    319320    boolean_options = [] 
    320321 
     
    329330    jsspecify = None 
    330331    grid = None 
    331     full_output = False 
     332    silent = False 
    332333    html = False 
    333334    record = False 
     335    parallel = False 
    334336 
    335337    def initialize_options(self): 
     
    341343    def run(self): 
    342344 
    343         if not self.checkIndicopPackages(): 
     345        if not self.checkTestPackages(): 
    344346            print "Please install those missing packages before launching the tests again" 
    345347            sys.exit(-1) 
    346348 
    347349        #missing jars will be downloaded automatically 
    348         if not self.checkIndicopJars(): 
     350        if not self.checkTestJars(): 
    349351            print "Some jars could not be downloaded. Please download the missing jars manually" 
    350352            sys.exit(-1) 
     
    361363        if self.jsspecify and 'jsunit' not in testsToRun: 
    362364            testsToRun.append('jsunit') 
    363         if self.specify != None and 'specify' not in testsToRun: 
    364             testsToRun.append('specify') 
    365365 
    366366        if testsToRun == []: 
     
    368368 
    369369 
    370         options = {'verbose': self.full_output, 
     370        options = {'silent': self.silent, 
    371371                   'html': self.html, 
    372372                   'specify': self.specify, 
    373373                   'coverage': self.coverage, 
    374                    'record': self.record} 
     374                   'record': self.record, 
     375                   'parallel': self.parallel} 
     376 
     377        # get only options that are active 
     378        options = dict((k,v) for (k,v) in options.iteritems() if v) 
    375379 
    376380        #this variable will tell what to do with the databases 
     
    378382 
    379383        manager = TestManager() 
     384 
    380385        result = manager.main(fakeDBPolicy, testsToRun, options) 
    381386 
    382         print result 
    383  
     387        sys.exit(result) 
    384388 
    385389    def checkDBStatus(self, testsToRun, specify): 
     
    389393 
    390394        fakeDBPolicy = 0 
    391         if ('functional' in testsToRun) or ('grid' in testsToRun) or ((specify != None) and (specify.find('unit/') < 0)): 
     395        if ('functional' in testsToRun) or ('grid' in testsToRun): 
    392396 
    393397            params = Config.getInstance().getDBConnectionParams() 
     
    414418            else: 
    415419                fakeDBPolicy = 2 
    416         elif 'unit' in testsToRun or 'specify' in testsToRun: 
     420        elif 'unit' in testsToRun: 
    417421            fakeDBPolicy = 1 
    418422 
    419423        return fakeDBPolicy 
    420424 
    421     def checkIndicopPackages(self): 
     425    def checkTestPackages(self): 
    422426        packagesList = ['figleaf', 
    423427                        'nose', 
     428                        'rednose', 
    424429                        'selenium', 
    425430                        'twill'] 
     
    436441        return validPackages 
    437442 
    438     def checkIndicopJars(self): 
     443    def checkTestJars(self): 
     444        """ 
     445        check if needed jars are here, if not, 
     446        dowload them and unzip the file if necessary 
     447        """ 
     448 
    439449        from indico.tests import TestConfig 
    440450 
    441         """check if needed jars are here, if not, dowloading them and unzip a file if necessary""" 
    442451        jarsList = {} 
    443452        currentFilePath = os.path.dirname(__file__) 
     
    448457                                                           'javascript', 
    449458                                                           'unit'), 
    450                                   'url':      TestConfig.getInstance().getJsunitURL(), 
    451                                   'filename': TestConfig.getInstance().getJsunitFilename()} 
     459                                  'url':      TestConfig.getInstance().getJSUnitURL(), 
     460                                  'filename': TestConfig.getInstance().getJSUnitFilename()} 
    452461 
    453462            jarsList['jscoverage'] = {'path':     os.path.join(testModPath, 
     
    455464                                                               'unit', 
    456465                                                               'plugins'), 
    457                                       'url':      TestConfig.getInstance().getJscoverageURL(), 
    458                                       'filename': TestConfig.getInstance().getJscoverageFilename()} 
     466                                      'url':      TestConfig.getInstance().getJSCoverageURL(), 
     467                                      'filename': TestConfig.getInstance().getJSCoverageFilename()} 
    459468 
    460469            jarsList['selenium'] = {'path':      os.path.join(testModPath, 
     
    475484            #check if jar is already here 
    476485            if not os.path.exists(os.path.join(jar['path'], jar['filename'])): 
    477                 print "Downloading %s..." % jar['filename'] 
     486                print "Downloading %s to %s..." % (jar['url'], jar['path']) 
    478487                try: 
    479488                    self.download(jar['url'], jar['path']) 
Note: See TracChangeset for help on using the changeset viewer.