~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/scripts/trial.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
# See LICENSE for details.
5
5
 
6
6
 
7
 
import sys, os, shutil, random, gc, time, sets
 
7
import sys, os, random, gc, time, sets
8
8
 
9
9
from twisted.internet import defer
10
10
from twisted.application import app
11
 
from twisted.python import usage, reflect, failure, log
 
11
from twisted.python import usage, reflect, failure
12
12
from twisted import plugin
13
13
from twisted.python.util import spewer
14
14
from twisted.trial import runner, itrial, reporter
84
84
            and os.path.splitext(basename)[1] == ('.py'))
85
85
 
86
86
 
87
 
class Options(usage.Options):
 
87
def _zshReporterAction():
 
88
    return "(%s)" % (" ".join([p.longOpt for p in plugin.getPlugins(itrial.IReporter)]),)
 
89
 
 
90
class Options(usage.Options, app.ReactorSelectionMixin):
88
91
    synopsis = """%s [options] [[file|package|module|TestCase|testmethod]...]
89
92
    """ % (os.path.basename(sys.argv[0]),)
90
93
 
98
101
                ["nopm", None, "don't automatically jump into debugger for "
99
102
                 "postmorteming of exceptions"],
100
103
                ["dry-run", 'n', "do everything but run the tests"],
 
104
                ["force-gc", None, "Have Trial run gc.collect() before and "
 
105
                 "after each test case."],
101
106
                ["profile", None, "Run tests under the Python profiler"],
102
107
                ["until-failure", "u", "Repeat test until it fails"],
103
108
                ["no-recurse", "N", "Don't recurse into packages"],
104
 
                ['suppresswarnings', None,
105
 
                 'Only print warnings to log, not stdout. DEPRECATED.'],
106
109
                ['help-reporters', None,
107
110
                 "Help on available output plugins (reporters)"]
108
111
                ]
109
112
 
110
 
    optParameters = [["reactor", "r", None,
111
 
                      "Which reactor to use out of: " + \
112
 
                      ", ".join(app.reactorTypes.keys()) + "."],
113
 
                     ["logfile", "l", "test.log", "log file name"],
114
 
                     ["random", "z", None,
115
 
                      "Run tests in random order using the specified seed"],
116
 
                     ['temp-directory', None, '_trial_temp',
117
 
                      'Path to use as working directory for tests.']]
 
113
    optParameters = [
 
114
        ["logfile", "l", "test.log", "log file name"],
 
115
        ["random", "z", None,
 
116
         "Run tests in random order using the specified seed"],
 
117
        ['temp-directory', None, '_trial_temp',
 
118
         'Path to use as working directory for tests.'],
 
119
        ['reporter', None, 'verbose',
 
120
         'The reporter to use for this test run.  See --help-reporters for '
 
121
         'more info.']]
118
122
 
119
 
    zsh_actions = {"reactor":"(%s)" % " ".join(app.reactorTypes.keys()),
120
 
                   "tbformat":"(plain emacs cgitb)"}
 
123
    zsh_actions = {"tbformat":"(plain emacs cgitb)",
 
124
                   "reporter":_zshReporterAction}
121
125
    zsh_actionDescr = {"logfile":"log file name",
122
126
                       "random":"random seed"}
123
127
    zsh_extras = ["*:file|module|package|TestCase|testMethod:_files -g '*.py'"]
128
132
 
129
133
    def __init__(self):
130
134
        self['tests'] = sets.Set()
131
 
        self._loadReporters()
132
 
 
133
 
        # Yes, I know I'm mutating a class variable.
134
 
        self.zsh_actions["reporter"] = "(%s)" % " ".join(self.optToQual.keys())
135
135
        usage.Options.__init__(self)
136
136
 
137
 
    def _loadReporters(self):
138
 
        if self._supportsColor():
139
 
            default = 'verbose'
140
 
        else:
141
 
            default = 'bwverbose'
142
 
        self.optToQual = {}
143
 
        for p in plugin.getPlugins(itrial.IReporter):
144
 
            qual = "%s.%s" % (p.module, p.klass)
145
 
            self.optToQual[p.longOpt] = qual
146
 
            if p.longOpt == default:
147
 
                self['reporter'] = reflect.namedAny(qual)
148
 
 
149
 
    def _supportsColor(self):
150
 
        # assuming stderr
151
 
        import sys
152
 
        if not sys.stderr.isatty():
153
 
            return False # auto color only on TTYs
154
 
        try:
155
 
            import curses
156
 
            curses.setupterm()
157
 
            return curses.tigetnum("colors") > 2
158
 
        except:
159
 
            # guess false in case of error
160
 
            return False
161
 
 
162
 
    def opt_reactor(self, reactorName):
163
 
        # this must happen before parseArgs does lots of imports
164
 
        app.installReactor(reactorName)
165
 
        print "Using %s reactor" % app.reactorTypes[reactorName]
166
 
 
167
137
    def opt_coverage(self):
168
138
        """
169
 
        Generate coverage information in the given directory (relative to
170
 
        trial temporary working directory). Requires Python 2.3.3.
 
139
        Generate coverage information in the _trial_temp/coverage. Requires
 
140
        Python 2.3.3.
171
141
        """
172
142
        coverdir = 'coverage'
173
143
        print "Setting coverage directory to %s." % (coverdir,)
229
199
        """Print an insanely verbose log of everything that happens.  Useful
230
200
        when debugging freezes or locks in complex code."""
231
201
        sys.settrace(spewer)
232
 
        
233
 
    def opt_reporter(self, opt):
234
 
        """The reporter to use for this test run.  See --help-reporters
235
 
        for more info.
236
 
        """
237
 
        if opt in self.optToQual:
238
 
            opt = self.optToQual[opt]
239
 
        else:
240
 
            raise usage.UsageError("Only pass names of Reporter plugins to "
241
 
                                   "--reporter. See --help-reporters for "
242
 
                                   "more info.")
243
 
        self['reporter'] = reflect.namedAny(opt)
 
202
 
244
203
 
245
204
    def opt_help_reporters(self):
246
205
        synopsis = ("Trial's output can be customized using plugins called "
251
210
            print '   ', p.longOpt, '\t', p.description
252
211
        print
253
212
        sys.exit(0)
254
 
        
 
213
 
255
214
    def opt_disablegc(self):
256
215
        """Disable the garbage collector"""
257
216
        gc.disable()
302
261
        if self.extra is not None:
303
262
            self['tests'].update(self.extra)
304
263
 
 
264
    def _loadReporterByName(self, name):
 
265
        for p in plugin.getPlugins(itrial.IReporter):
 
266
            qual = "%s.%s" % (p.module, p.klass)
 
267
            if p.longOpt == name:
 
268
                return reflect.namedAny(qual)
 
269
        raise usage.UsageError("Only pass names of Reporter plugins to "
 
270
                               "--reporter. See --help-reporters for "
 
271
                               "more info.")
 
272
 
 
273
 
305
274
    def postOptions(self):
306
 
        if self['suppresswarnings']:
307
 
            warnings.warn('--suppresswarnings deprecated. Is a no-op',
308
 
                          category=DeprecationWarning)
 
275
 
 
276
        # Only load reporters now, as opposed to any earlier, to avoid letting
 
277
        # application-defined plugins muck up reactor selecting by importing
 
278
        # t.i.reactor and causing the default to be installed.
 
279
        self['reporter'] = self._loadReporterByName(self['reporter'])
 
280
 
309
281
        if not self.has_key('tbformat'):
310
282
            self['tbformat'] = 'default'
311
283
        if self['nopm']:
314
286
                                       "--nopm ")
315
287
            failure.DO_POST_MORTEM = False
316
288
 
317
 
    
 
289
 
318
290
def _initialDebugSetup(config):
319
291
    # do this part of debug setup first for easy debugging of import failures
320
292
    if config['debug']:
325
297
 
326
298
def _getSuite(config):
327
299
    loader = _getLoader(config)
328
 
    suite = runner.TestSuite()
329
300
    recurse = not config['no-recurse']
330
 
    for test in config['tests']:
331
 
        if isinstance(test, str):
332
 
            suite.addTest(loader.loadByName(test, recurse))
333
 
        else:
334
 
            suite.addTest(loader.loadAnything(test, recurse))
335
 
    return suite
336
 
    
 
301
    return loader.loadByNames(config['tests'], recurse)
 
302
 
337
303
 
338
304
def _getLoader(config):
339
305
    loader = runner.TestLoader()
342
308
        randomer.seed(config['random'])
343
309
        loader.sorter = lambda x : randomer.random()
344
310
        print 'Running tests shuffled with seed %d\n' % config['random']
 
311
    if config['force-gc']:
 
312
        loader.forceGarbageCollection = True
345
313
    return loader
346
314
 
347
315