blob: 0b37306a6236dcab88955b7896a5b4d61a5569b0 [file] [log] [blame]
Brett Cannonf1cfb622003-05-04 21:15:27 +00001"""Supporting definitions for the Python regression tests."""
Guido van Rossum3bead091992-01-27 17:00:37 +00002
Barry Warsaw408b6d32002-07-30 23:27:12 +00003if __name__ != 'test.test_support':
4 raise ImportError, 'test_support must be imported from the test package'
5
Thomas Wouters902d6eb2007-01-09 23:18:33 +00006from contextlib import contextmanager
Fred Drakecd1b1dd2001-03-21 18:26:33 +00007import sys
Thomas Wouters902d6eb2007-01-09 23:18:33 +00008import warnings
Fred Drakecd1b1dd2001-03-21 18:26:33 +00009
Fred Drake1790dd42000-07-24 06:55:00 +000010class Error(Exception):
Fred Drake004d5e62000-10-23 17:22:08 +000011 """Base class for regression test exceptions."""
Fred Drake1790dd42000-07-24 06:55:00 +000012
13class TestFailed(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000014 """Test failed."""
Fred Drake1790dd42000-07-24 06:55:00 +000015
16class TestSkipped(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000017 """Test skipped.
Fred Drake1790dd42000-07-24 06:55:00 +000018
Fred Drake004d5e62000-10-23 17:22:08 +000019 This can be raised to indicate that a test was deliberatly
20 skipped, but not because a feature wasn't available. For
21 example, if some resource can't be used, such as the network
22 appears to be unavailable, this should be raised instead of
23 TestFailed.
Fred Drake004d5e62000-10-23 17:22:08 +000024 """
Fred Drake1790dd42000-07-24 06:55:00 +000025
Fred Drake9a0db072003-02-03 15:19:30 +000026class ResourceDenied(TestSkipped):
27 """Test skipped because it requested a disallowed resource.
28
29 This is raised when a test calls requires() for a resource that
30 has not be enabled. It is used to distinguish between expected
31 and unexpected skips.
32 """
33
Barry Warsawc0fb6052001-08-20 22:29:23 +000034verbose = 1 # Flag set to 0 by regrtest.py
Thomas Wouters477c8d52006-05-27 19:21:47 +000035use_resources = None # Flag set to [] by regrtest.py
36max_memuse = 0 # Disable bigmem tests (they will still be run with
37 # small sizes, to make sure they work.)
Guido van Rossum531661c1996-12-20 02:58:22 +000038
Tim Peters8dee8092001-09-25 20:05:11 +000039# _original_stdout is meant to hold stdout at the time regrtest began.
40# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
41# The point is to have some flavor of stdout the user can actually see.
42_original_stdout = None
43def record_original_stdout(stdout):
44 global _original_stdout
45 _original_stdout = stdout
46
47def get_original_stdout():
48 return _original_stdout or sys.stdout
49
Guido van Rossum3bead091992-01-27 17:00:37 +000050def unload(name):
Fred Drake004d5e62000-10-23 17:22:08 +000051 try:
52 del sys.modules[name]
53 except KeyError:
54 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000055
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000056def unlink(filename):
57 import os
58 try:
59 os.unlink(filename)
60 except OSError:
61 pass
62
Guido van Rossum3bead091992-01-27 17:00:37 +000063def forget(modname):
Brett Cannonf1cfb622003-05-04 21:15:27 +000064 '''"Forget" a module was ever imported by removing it from sys.modules and
65 deleting any .pyc and .pyo files.'''
Fred Drake004d5e62000-10-23 17:22:08 +000066 unload(modname)
Fred Drakecd1b1dd2001-03-21 18:26:33 +000067 import os
Fred Drake004d5e62000-10-23 17:22:08 +000068 for dirname in sys.path:
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000069 unlink(os.path.join(dirname, modname + os.extsep + 'pyc'))
Brett Cannonf1cfb622003-05-04 21:15:27 +000070 # Deleting the .pyo file cannot be within the 'try' for the .pyc since
71 # the chance exists that there is no .pyc (and thus the 'try' statement
72 # is exited) but there is a .pyo file.
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000073 unlink(os.path.join(dirname, modname + os.extsep + 'pyo'))
Guido van Rossum3bead091992-01-27 17:00:37 +000074
Tim Petersb4ee4eb2002-12-04 03:26:57 +000075def is_resource_enabled(resource):
Brett Cannonf1cfb622003-05-04 21:15:27 +000076 """Test whether a resource is enabled. Known resources are set by
77 regrtest.py."""
Tim Petersb4ee4eb2002-12-04 03:26:57 +000078 return use_resources is not None and resource in use_resources
79
Barry Warsawc0fb6052001-08-20 22:29:23 +000080def requires(resource, msg=None):
Brett Cannonf1cfb622003-05-04 21:15:27 +000081 """Raise ResourceDenied if the specified resource is not available.
82
83 If the caller's module is __main__ then automatically return True. The
84 possibility of False being returned occurs when regrtest.py is executing."""
Skip Montanarod839ecd2003-04-24 19:06:57 +000085 # see if the caller's module is __main__ - if so, treat as if
86 # the resource was set
87 if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
88 return
Tim Petersb4ee4eb2002-12-04 03:26:57 +000089 if not is_resource_enabled(resource):
Barry Warsawc0fb6052001-08-20 22:29:23 +000090 if msg is None:
91 msg = "Use of the `%s' resource not enabled" % resource
Fred Drake9a0db072003-02-03 15:19:30 +000092 raise ResourceDenied(msg)
Barry Warsawc0fb6052001-08-20 22:29:23 +000093
Thomas Wouters0e3f5912006-08-11 14:57:12 +000094def bind_port(sock, host='', preferred_port=54321):
95 """Try to bind the sock to a port. If we are running multiple
96 tests and we don't try multiple ports, the test can fails. This
97 makes the test more robust."""
98
99 import socket, errno
100 # some random ports that hopefully no one is listening on.
101 for port in [preferred_port, 9907, 10243, 32999]:
102 try:
103 sock.bind((host, port))
104 return port
Guido van Rossumb940e112007-01-10 16:19:56 +0000105 except socket.error as e:
106 (err, msg) = e
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000107 if err != errno.EADDRINUSE:
108 raise
109 print >>sys.__stderr__, \
110 ' WARNING: failed to listen on port %d, trying another' % port
111 raise TestFailed, 'unable to find port to listen on'
112
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000113FUZZ = 1e-6
114
115def fcmp(x, y): # fuzzy comparison function
Neal Norwitz79212992006-08-21 16:27:31 +0000116 if isinstance(x, float) or isinstance(y, float):
Fred Drake004d5e62000-10-23 17:22:08 +0000117 try:
Fred Drake004d5e62000-10-23 17:22:08 +0000118 fuzz = (abs(x) + abs(y)) * FUZZ
119 if abs(x-y) <= fuzz:
120 return 0
121 except:
122 pass
Neal Norwitz79212992006-08-21 16:27:31 +0000123 elif type(x) == type(y) and isinstance(x, (tuple, list)):
Fred Drake004d5e62000-10-23 17:22:08 +0000124 for i in range(min(len(x), len(y))):
125 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +0000126 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +0000127 return outcome
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000128 return (len(x) > len(y)) - (len(x) < len(y))
129 return (x > y) - (x < y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000130
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000131try:
132 unicode
Neal Norwitz79212992006-08-21 16:27:31 +0000133 have_unicode = True
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000134except NameError:
Neal Norwitz79212992006-08-21 16:27:31 +0000135 have_unicode = False
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000136
Finn Bock57bc5fa2002-11-01 18:02:03 +0000137is_jython = sys.platform.startswith('java')
138
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000139import os
Barry Warsaw559f6682001-03-23 18:04:02 +0000140# Filename used for testing
141if os.name == 'java':
142 # Jython disallows @ in module names
143 TESTFN = '$test'
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000144elif os.name == 'riscos':
145 TESTFN = 'testfile'
146else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000147 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +0000148 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000149 if have_unicode:
Mark Hammondb337dd92003-12-03 01:27:23 +0000150 # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
151 # TESTFN_UNICODE is a filename that can be encoded using the
152 # file system encoding, but *not* with the default (ascii) encoding
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000153 if isinstance('', unicode):
154 # python -U
155 # XXX perhaps unicode() should accept Unicode strings?
Tim Petersc6c5ece2003-12-04 05:39:43 +0000156 TESTFN_UNICODE = "@test-\xe0\xf2"
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000157 else:
Tim Petersc6c5ece2003-12-04 05:39:43 +0000158 # 2 latin characters.
159 TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1")
160 TESTFN_ENCODING = sys.getfilesystemencoding()
161 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
Mark Hammondb337dd92003-12-03 01:27:23 +0000162 # able to be encoded by *either* the default or filesystem encoding.
Tim Petersc6c5ece2003-12-04 05:39:43 +0000163 # This test really only makes sense on Windows NT platforms
Mark Hammond2e8624c2003-12-03 22:16:47 +0000164 # which have special Unicode support in posixmodule.
Tim Petersc6c5ece2003-12-04 05:39:43 +0000165 if (not hasattr(sys, "getwindowsversion") or
166 sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
Tim Peters58eb11c2004-01-18 20:29:55 +0000167 TESTFN_UNICODE_UNENCODEABLE = None
Mark Hammondb337dd92003-12-03 01:27:23 +0000168 else:
Mark Hammond2e8624c2003-12-03 22:16:47 +0000169 # Japanese characters (I think - from bug 846133)
Martin v. Löwise2713be2005-03-08 15:03:08 +0000170 TESTFN_UNICODE_UNENCODEABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
Mark Hammond2e8624c2003-12-03 22:16:47 +0000171 try:
172 # XXX - Note - should be using TESTFN_ENCODING here - but for
Tim Petersc6c5ece2003-12-04 05:39:43 +0000173 # Windows, "mbcs" currently always operates as if in
Mark Hammond2e8624c2003-12-03 22:16:47 +0000174 # errors=ignore' mode - hence we get '?' characters rather than
175 # the exception. 'Latin1' operates as we expect - ie, fails.
176 # See [ 850997 ] mbcs encoding ignores errors
177 TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
178 except UnicodeEncodeError:
179 pass
180 else:
181 print \
182 'WARNING: The filename %r CAN be encoded by the filesystem. ' \
183 'Unicode filename tests may not be effective' \
184 % TESTFN_UNICODE_UNENCODEABLE
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000185
186# Make sure we can write to TESTFN, try in /tmp if we can't
187fp = None
188try:
189 fp = open(TESTFN, 'w+')
190except IOError:
191 TMP_TESTFN = os.path.join('/tmp', TESTFN)
192 try:
193 fp = open(TMP_TESTFN, 'w+')
194 TESTFN = TMP_TESTFN
195 del TMP_TESTFN
196 except IOError:
Tim Peters3de75262002-11-09 05:26:15 +0000197 print ('WARNING: tests will fail, unable to write to: %s or %s' %
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000198 (TESTFN, TMP_TESTFN))
199if fp is not None:
200 fp.close()
Neal Norwitz0e17f8c2006-01-23 07:51:27 +0000201 unlink(TESTFN)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000202del os, fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000203
Guido van Rossume26132c1998-04-23 20:13:30 +0000204def findfile(file, here=__file__):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000205 """Try to find a file on sys.path and the working directory. If it is not
206 found the argument passed to the function is returned (this does not
207 necessarily signal failure; could still be the legitimate path)."""
Fred Drake004d5e62000-10-23 17:22:08 +0000208 import os
209 if os.path.isabs(file):
210 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000211 path = sys.path
212 path = [os.path.dirname(here)] + path
213 for dn in path:
214 fn = os.path.join(dn, file)
215 if os.path.exists(fn): return fn
216 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000217
218def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000219 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000220
Skip Montanaroc955f892001-01-20 19:12:54 +0000221 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000222 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000223 """
Tim Peters983874d2001-01-19 05:59:21 +0000224
Tim Petersd2bf3b72001-01-18 02:22:22 +0000225 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000226 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000227
Tim Petersc2fe6182001-10-30 23:20:46 +0000228def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000229 """Raise TestFailed if a == b is false.
230
231 This is better than verify(a == b) because, in case of failure, the
232 error message incorporates repr(a) and repr(b) so you can see the
233 inputs.
234
235 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
236 former is tested.
237 """
238
Tim Petersc2fe6182001-10-30 23:20:46 +0000239 if not (a == b):
240 raise TestFailed, "%r == %r" % (a, b)
241
Tim Peters2f228e72001-05-13 00:19:31 +0000242def sortdict(dict):
243 "Like repr(dict), but in sorted order."
244 items = dict.items()
245 items.sort()
246 reprpairs = ["%r: %r" % pair for pair in items]
247 withcommas = ", ".join(reprpairs)
248 return "{%s}" % withcommas
249
Thomas Wouters89f507f2006-12-13 04:49:30 +0000250def check_syntax_error(testcase, statement):
Jeremy Hylton47793992001-02-19 15:35:26 +0000251 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000252 compile(statement, '<test string>', 'exec')
Jeremy Hylton47793992001-02-19 15:35:26 +0000253 except SyntaxError:
254 pass
255 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000256 testcase.fail('Missing SyntaxError: "%s"' % statement)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000257
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000258def open_urlresource(url):
259 import urllib, urlparse
260 import os.path
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000261
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000262 filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
263
264 for path in [os.path.curdir, os.path.pardir]:
265 fn = os.path.join(path, filename)
266 if os.path.exists(fn):
267 return open(fn)
268
269 requires('urlfetch')
270 print >> get_original_stdout(), '\tfetching %s ...' % url
271 fn, _ = urllib.urlretrieve(url, filename)
272 return open(fn)
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000273
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000274@contextmanager
275def guard_warnings_filter():
276 """Guard the warnings filter from being permanently changed."""
277 original_filters = warnings.filters[:]
278 try:
279 yield
280 finally:
281 warnings.filters = original_filters
282
283class EnvironmentVarGuard(object):
284
285 """Class to help protect the environment variable properly. Can be used as
286 a context manager."""
287
288 def __init__(self):
289 from os import environ
290 self._environ = environ
291 self._unset = set()
292 self._reset = dict()
293
294 def set(self, envvar, value):
295 if envvar not in self._environ:
296 self._unset.add(envvar)
297 else:
298 self._reset[envvar] = self._environ[envvar]
299 self._environ[envvar] = value
300
301 def unset(self, envvar):
302 if envvar in self._environ:
303 self._reset[envvar] = self._environ[envvar]
304 del self._environ[envvar]
305
306 def __enter__(self):
307 return self
308
309 def __exit__(self, *ignore_exc):
310 for envvar, value in self._reset.iteritems():
311 self._environ[envvar] = value
312 for unset in self._unset:
313 del self._environ[unset]
314
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000315
316#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317# Decorator for running a function in a different locale, correctly resetting
318# it afterwards.
319
320def run_with_locale(catstr, *locales):
321 def decorator(func):
322 def inner(*args, **kwds):
323 try:
324 import locale
325 category = getattr(locale, catstr)
326 orig_locale = locale.setlocale(category)
327 except AttributeError:
328 # if the test author gives us an invalid category string
329 raise
330 except:
331 # cannot retrieve original locale, so do nothing
332 locale = orig_locale = None
333 else:
334 for loc in locales:
335 try:
336 locale.setlocale(category, loc)
337 break
338 except:
339 pass
340
341 # now run the function, resetting the locale on exceptions
342 try:
343 return func(*args, **kwds)
344 finally:
345 if locale and orig_locale:
346 locale.setlocale(category, orig_locale)
347 inner.func_name = func.func_name
348 inner.__doc__ = func.__doc__
349 return inner
350 return decorator
351
352#=======================================================================
353# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
354
355# Some handy shorthands. Note that these are used for byte-limits as well
356# as size-limits, in the various bigmem tests
357_1M = 1024*1024
358_1G = 1024 * _1M
359_2G = 2 * _1G
360
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000361# Hack to get at the maximum value an internal index can take.
362class _Dummy:
363 def __getslice__(self, i, j):
364 return j
365MAX_Py_ssize_t = _Dummy()[:]
366
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367def set_memlimit(limit):
368 import re
369 global max_memuse
370 sizes = {
371 'k': 1024,
372 'm': _1M,
373 'g': _1G,
374 't': 1024*_1G,
375 }
376 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
377 re.IGNORECASE | re.VERBOSE)
378 if m is None:
379 raise ValueError('Invalid memory limit %r' % (limit,))
380 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000381 if memlimit > MAX_Py_ssize_t:
382 memlimit = MAX_Py_ssize_t
383 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000384 raise ValueError('Memory limit %r too low to be useful' % (limit,))
385 max_memuse = memlimit
386
387def bigmemtest(minsize, memuse, overhead=5*_1M):
388 """Decorator for bigmem tests.
389
390 'minsize' is the minimum useful size for the test (in arbitrary,
391 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
392 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
393 independant of the testsize, and defaults to 5Mb.
394
395 The decorator tries to guess a good value for 'size' and passes it to
396 the decorated test function. If minsize * memuse is more than the
397 allowed memory use (as defined by max_memuse), the test is skipped.
398 Otherwise, minsize is adjusted upward to use up to max_memuse.
399 """
400 def decorator(f):
401 def wrapper(self):
402 if not max_memuse:
403 # If max_memuse is 0 (the default),
404 # we still want to run the tests with size set to a few kb,
405 # to make sure they work. We still want to avoid using
406 # too much memory, though, but we do that noisily.
407 maxsize = 5147
408 self.failIf(maxsize * memuse + overhead > 20 * _1M)
409 else:
410 maxsize = int((max_memuse - overhead) / memuse)
411 if maxsize < minsize:
412 # Really ought to print 'test skipped' or something
413 if verbose:
414 sys.stderr.write("Skipping %s because of memory "
415 "constraint\n" % (f.__name__,))
416 return
417 # Try to keep some breathing room in memory use
418 maxsize = max(maxsize - 50 * _1M, minsize)
419 return f(self, maxsize)
420 wrapper.minsize = minsize
421 wrapper.memuse = memuse
422 wrapper.overhead = overhead
423 return wrapper
424 return decorator
425
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000426def bigaddrspacetest(f):
427 """Decorator for tests that fill the address space."""
428 def wrapper(self):
429 if max_memuse < MAX_Py_ssize_t:
430 if verbose:
431 sys.stderr.write("Skipping %s because of memory "
432 "constraint\n" % (f.__name__,))
433 else:
434 return f(self)
435 return wrapper
436
Thomas Wouters477c8d52006-05-27 19:21:47 +0000437#=======================================================================
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000438# Preliminary PyUNIT integration.
439
440import unittest
441
442
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000443class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000444 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000445 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000446 test(result)
447 return result
448
449
Fred Drake26641032001-10-04 19:46:07 +0000450def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000451 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000452 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000453 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000454 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000455 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000456
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000457 result = runner.run(suite)
458 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000459 if len(result.errors) == 1 and not result.failures:
460 err = result.errors[0][1]
461 elif len(result.failures) == 1 and not result.errors:
462 err = result.failures[0][1]
463 else:
Fred Drake26641032001-10-04 19:46:07 +0000464 if testclass is None:
465 msg = "errors occurred; run in verbose mode for details"
466 else:
467 msg = "errors occurred in %s.%s" \
468 % (testclass.__module__, testclass.__name__)
469 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000470 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000471
Barry Warsawc10d6902001-09-20 06:30:41 +0000472
Walter Dörwald21d3a322003-05-01 17:45:56 +0000473def run_unittest(*classes):
474 """Run tests from unittest.TestCase-derived classes."""
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000475 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000476 for cls in classes:
Raymond Hettingerf3590622003-07-16 04:29:42 +0000477 if isinstance(cls, (unittest.TestSuite, unittest.TestCase)):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000478 suite.addTest(cls)
479 else:
480 suite.addTest(unittest.makeSuite(cls))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000481 if len(classes)==1:
482 testclass = classes[0]
483 else:
484 testclass = None
485 run_suite(suite, testclass)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000486
Barry Warsawc10d6902001-09-20 06:30:41 +0000487
Tim Petersa0a62222001-09-09 06:12:01 +0000488#=======================================================================
489# doctest driver.
490
491def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000492 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000493
494 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000495 test_support's belief about verbosity on to doctest. Else doctest's
496 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000497 """
498
499 import doctest
500
501 if verbosity is None:
502 verbosity = verbose
503 else:
504 verbosity = None
505
Tim Peters342ca752001-09-25 19:13:20 +0000506 # Direct doctest output (normally just errors) to real stdout; doctest
507 # output shouldn't be compared by regrtest.
508 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000509 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000510 try:
511 f, t = doctest.testmod(module, verbose=verbosity)
512 if f:
513 raise TestFailed("%d of %d doctests failed" % (f, t))
514 finally:
515 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000516 if verbose:
Raymond Hettinger1ba24b42003-05-17 01:59:57 +0000517 print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t)
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000518 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519
520#=======================================================================
521# Threading support to prevent reporting refleaks when running regrtest.py -R
522
523def threading_setup():
524 import threading
525 return len(threading._active), len(threading._limbo)
526
527def threading_cleanup(num_active, num_limbo):
528 import threading
529 import time
530
531 _MAX_COUNT = 10
532 count = 0
533 while len(threading._active) != num_active and count < _MAX_COUNT:
534 count += 1
535 time.sleep(0.1)
536
537 count = 0
538 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
539 count += 1
540 time.sleep(0.1)
541
542def reap_children():
543 """Use this function at the end of test_main() whenever sub-processes
544 are started. This will help ensure that no extra children (zombies)
545 stick around to hog resources and create problems when looking
546 for refleaks.
547 """
548
549 # Reap all our dead child processes so we don't leave zombies around.
550 # These hog resources and might be causing some of the buildbots to die.
551 import os
552 if hasattr(os, 'waitpid'):
553 any_process = -1
554 while True:
555 try:
556 # This will raise an exception on Windows. That's ok.
557 pid, status = os.waitpid(any_process, os.WNOHANG)
558 if pid == 0:
559 break
560 except:
561 break