blob: 2c196984805a09fa2179e0894baaae5d9596d101 [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
105 except socket.error, (err, msg):
106 if err != errno.EADDRINUSE:
107 raise
108 print >>sys.__stderr__, \
109 ' WARNING: failed to listen on port %d, trying another' % port
110 raise TestFailed, 'unable to find port to listen on'
111
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000112FUZZ = 1e-6
113
114def fcmp(x, y): # fuzzy comparison function
Neal Norwitz79212992006-08-21 16:27:31 +0000115 if isinstance(x, float) or isinstance(y, float):
Fred Drake004d5e62000-10-23 17:22:08 +0000116 try:
Fred Drake004d5e62000-10-23 17:22:08 +0000117 fuzz = (abs(x) + abs(y)) * FUZZ
118 if abs(x-y) <= fuzz:
119 return 0
120 except:
121 pass
Neal Norwitz79212992006-08-21 16:27:31 +0000122 elif type(x) == type(y) and isinstance(x, (tuple, list)):
Fred Drake004d5e62000-10-23 17:22:08 +0000123 for i in range(min(len(x), len(y))):
124 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +0000125 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +0000126 return outcome
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000127 return (len(x) > len(y)) - (len(x) < len(y))
128 return (x > y) - (x < y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000129
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000130try:
131 unicode
Neal Norwitz79212992006-08-21 16:27:31 +0000132 have_unicode = True
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000133except NameError:
Neal Norwitz79212992006-08-21 16:27:31 +0000134 have_unicode = False
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000135
Finn Bock57bc5fa2002-11-01 18:02:03 +0000136is_jython = sys.platform.startswith('java')
137
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000138import os
Barry Warsaw559f6682001-03-23 18:04:02 +0000139# Filename used for testing
140if os.name == 'java':
141 # Jython disallows @ in module names
142 TESTFN = '$test'
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000143elif os.name == 'riscos':
144 TESTFN = 'testfile'
145else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000146 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +0000147 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000148 if have_unicode:
Mark Hammondb337dd92003-12-03 01:27:23 +0000149 # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
150 # TESTFN_UNICODE is a filename that can be encoded using the
151 # file system encoding, but *not* with the default (ascii) encoding
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000152 if isinstance('', unicode):
153 # python -U
154 # XXX perhaps unicode() should accept Unicode strings?
Tim Petersc6c5ece2003-12-04 05:39:43 +0000155 TESTFN_UNICODE = "@test-\xe0\xf2"
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000156 else:
Tim Petersc6c5ece2003-12-04 05:39:43 +0000157 # 2 latin characters.
158 TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1")
159 TESTFN_ENCODING = sys.getfilesystemencoding()
160 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
Mark Hammondb337dd92003-12-03 01:27:23 +0000161 # able to be encoded by *either* the default or filesystem encoding.
Tim Petersc6c5ece2003-12-04 05:39:43 +0000162 # This test really only makes sense on Windows NT platforms
Mark Hammond2e8624c2003-12-03 22:16:47 +0000163 # which have special Unicode support in posixmodule.
Tim Petersc6c5ece2003-12-04 05:39:43 +0000164 if (not hasattr(sys, "getwindowsversion") or
165 sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
Tim Peters58eb11c2004-01-18 20:29:55 +0000166 TESTFN_UNICODE_UNENCODEABLE = None
Mark Hammondb337dd92003-12-03 01:27:23 +0000167 else:
Mark Hammond2e8624c2003-12-03 22:16:47 +0000168 # Japanese characters (I think - from bug 846133)
Martin v. Löwise2713be2005-03-08 15:03:08 +0000169 TESTFN_UNICODE_UNENCODEABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
Mark Hammond2e8624c2003-12-03 22:16:47 +0000170 try:
171 # XXX - Note - should be using TESTFN_ENCODING here - but for
Tim Petersc6c5ece2003-12-04 05:39:43 +0000172 # Windows, "mbcs" currently always operates as if in
Mark Hammond2e8624c2003-12-03 22:16:47 +0000173 # errors=ignore' mode - hence we get '?' characters rather than
174 # the exception. 'Latin1' operates as we expect - ie, fails.
175 # See [ 850997 ] mbcs encoding ignores errors
176 TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
177 except UnicodeEncodeError:
178 pass
179 else:
180 print \
181 'WARNING: The filename %r CAN be encoded by the filesystem. ' \
182 'Unicode filename tests may not be effective' \
183 % TESTFN_UNICODE_UNENCODEABLE
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000184
185# Make sure we can write to TESTFN, try in /tmp if we can't
186fp = None
187try:
188 fp = open(TESTFN, 'w+')
189except IOError:
190 TMP_TESTFN = os.path.join('/tmp', TESTFN)
191 try:
192 fp = open(TMP_TESTFN, 'w+')
193 TESTFN = TMP_TESTFN
194 del TMP_TESTFN
195 except IOError:
Tim Peters3de75262002-11-09 05:26:15 +0000196 print ('WARNING: tests will fail, unable to write to: %s or %s' %
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000197 (TESTFN, TMP_TESTFN))
198if fp is not None:
199 fp.close()
Neal Norwitz0e17f8c2006-01-23 07:51:27 +0000200 unlink(TESTFN)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000201del os, fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000202
Guido van Rossume26132c1998-04-23 20:13:30 +0000203def findfile(file, here=__file__):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000204 """Try to find a file on sys.path and the working directory. If it is not
205 found the argument passed to the function is returned (this does not
206 necessarily signal failure; could still be the legitimate path)."""
Fred Drake004d5e62000-10-23 17:22:08 +0000207 import os
208 if os.path.isabs(file):
209 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000210 path = sys.path
211 path = [os.path.dirname(here)] + path
212 for dn in path:
213 fn = os.path.join(dn, file)
214 if os.path.exists(fn): return fn
215 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000216
217def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000218 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000219
Skip Montanaroc955f892001-01-20 19:12:54 +0000220 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000221 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000222 """
Tim Peters983874d2001-01-19 05:59:21 +0000223
Tim Petersd2bf3b72001-01-18 02:22:22 +0000224 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000225 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000226
Tim Petersc2fe6182001-10-30 23:20:46 +0000227def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000228 """Raise TestFailed if a == b is false.
229
230 This is better than verify(a == b) because, in case of failure, the
231 error message incorporates repr(a) and repr(b) so you can see the
232 inputs.
233
234 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
235 former is tested.
236 """
237
Tim Petersc2fe6182001-10-30 23:20:46 +0000238 if not (a == b):
239 raise TestFailed, "%r == %r" % (a, b)
240
Tim Peters2f228e72001-05-13 00:19:31 +0000241def sortdict(dict):
242 "Like repr(dict), but in sorted order."
243 items = dict.items()
244 items.sort()
245 reprpairs = ["%r: %r" % pair for pair in items]
246 withcommas = ", ".join(reprpairs)
247 return "{%s}" % withcommas
248
Thomas Wouters89f507f2006-12-13 04:49:30 +0000249def check_syntax_error(testcase, statement):
Jeremy Hylton47793992001-02-19 15:35:26 +0000250 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000251 compile(statement, '<test string>', 'exec')
Jeremy Hylton47793992001-02-19 15:35:26 +0000252 except SyntaxError:
253 pass
254 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000255 testcase.fail('Missing SyntaxError: "%s"' % statement)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000256
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000257def open_urlresource(url):
258 import urllib, urlparse
259 import os.path
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000260
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000261 filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
262
263 for path in [os.path.curdir, os.path.pardir]:
264 fn = os.path.join(path, filename)
265 if os.path.exists(fn):
266 return open(fn)
267
268 requires('urlfetch')
269 print >> get_original_stdout(), '\tfetching %s ...' % url
270 fn, _ = urllib.urlretrieve(url, filename)
271 return open(fn)
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000272
273@contextmanager
274def guard_warnings_filter():
275 """Guard the warnings filter from being permanently changed."""
276 original_filters = warnings.filters[:]
277 try:
278 yield
279 finally:
280 warnings.filters = original_filters
281
282class EnvironmentVarGuard(object):
283
284 """Class to help protect the environment variable properly. Can be used as
285 a context manager."""
286
287 def __init__(self):
288 from os import environ
289 self._environ = environ
290 self._unset = set()
291 self._reset = dict()
292
293 def set(self, envvar, value):
294 if envvar not in self._environ:
295 self._unset.add(envvar)
296 else:
297 self._reset[envvar] = self._environ[envvar]
298 self._environ[envvar] = value
299
300 def unset(self, envvar):
301 if envvar in self._environ:
302 self._reset[envvar] = self._environ[envvar]
303 del self._environ[envvar]
304
305 def __enter__(self):
306 return self
307
308 def __exit__(self, *ignore_exc):
309 for envvar, value in self._reset.iteritems():
310 self._environ[envvar] = value
311 for unset in self._unset:
312 del self._environ[unset]
313
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000314
315#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000316# Decorator for running a function in a different locale, correctly resetting
317# it afterwards.
318
319def run_with_locale(catstr, *locales):
320 def decorator(func):
321 def inner(*args, **kwds):
322 try:
323 import locale
324 category = getattr(locale, catstr)
325 orig_locale = locale.setlocale(category)
326 except AttributeError:
327 # if the test author gives us an invalid category string
328 raise
329 except:
330 # cannot retrieve original locale, so do nothing
331 locale = orig_locale = None
332 else:
333 for loc in locales:
334 try:
335 locale.setlocale(category, loc)
336 break
337 except:
338 pass
339
340 # now run the function, resetting the locale on exceptions
341 try:
342 return func(*args, **kwds)
343 finally:
344 if locale and orig_locale:
345 locale.setlocale(category, orig_locale)
346 inner.func_name = func.func_name
347 inner.__doc__ = func.__doc__
348 return inner
349 return decorator
350
351#=======================================================================
352# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
353
354# Some handy shorthands. Note that these are used for byte-limits as well
355# as size-limits, in the various bigmem tests
356_1M = 1024*1024
357_1G = 1024 * _1M
358_2G = 2 * _1G
359
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000360# Hack to get at the maximum value an internal index can take.
361class _Dummy:
362 def __getslice__(self, i, j):
363 return j
364MAX_Py_ssize_t = _Dummy()[:]
365
Thomas Wouters477c8d52006-05-27 19:21:47 +0000366def set_memlimit(limit):
367 import re
368 global max_memuse
369 sizes = {
370 'k': 1024,
371 'm': _1M,
372 'g': _1G,
373 't': 1024*_1G,
374 }
375 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
376 re.IGNORECASE | re.VERBOSE)
377 if m is None:
378 raise ValueError('Invalid memory limit %r' % (limit,))
379 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000380 if memlimit > MAX_Py_ssize_t:
381 memlimit = MAX_Py_ssize_t
382 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000383 raise ValueError('Memory limit %r too low to be useful' % (limit,))
384 max_memuse = memlimit
385
386def bigmemtest(minsize, memuse, overhead=5*_1M):
387 """Decorator for bigmem tests.
388
389 'minsize' is the minimum useful size for the test (in arbitrary,
390 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
391 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
392 independant of the testsize, and defaults to 5Mb.
393
394 The decorator tries to guess a good value for 'size' and passes it to
395 the decorated test function. If minsize * memuse is more than the
396 allowed memory use (as defined by max_memuse), the test is skipped.
397 Otherwise, minsize is adjusted upward to use up to max_memuse.
398 """
399 def decorator(f):
400 def wrapper(self):
401 if not max_memuse:
402 # If max_memuse is 0 (the default),
403 # we still want to run the tests with size set to a few kb,
404 # to make sure they work. We still want to avoid using
405 # too much memory, though, but we do that noisily.
406 maxsize = 5147
407 self.failIf(maxsize * memuse + overhead > 20 * _1M)
408 else:
409 maxsize = int((max_memuse - overhead) / memuse)
410 if maxsize < minsize:
411 # Really ought to print 'test skipped' or something
412 if verbose:
413 sys.stderr.write("Skipping %s because of memory "
414 "constraint\n" % (f.__name__,))
415 return
416 # Try to keep some breathing room in memory use
417 maxsize = max(maxsize - 50 * _1M, minsize)
418 return f(self, maxsize)
419 wrapper.minsize = minsize
420 wrapper.memuse = memuse
421 wrapper.overhead = overhead
422 return wrapper
423 return decorator
424
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000425def bigaddrspacetest(f):
426 """Decorator for tests that fill the address space."""
427 def wrapper(self):
428 if max_memuse < MAX_Py_ssize_t:
429 if verbose:
430 sys.stderr.write("Skipping %s because of memory "
431 "constraint\n" % (f.__name__,))
432 else:
433 return f(self)
434 return wrapper
435
Thomas Wouters477c8d52006-05-27 19:21:47 +0000436#=======================================================================
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000437# Preliminary PyUNIT integration.
438
439import unittest
440
441
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000442class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000443 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000444 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000445 test(result)
446 return result
447
448
Fred Drake26641032001-10-04 19:46:07 +0000449def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000450 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000451 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000452 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000453 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000454 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000455
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000456 result = runner.run(suite)
457 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000458 if len(result.errors) == 1 and not result.failures:
459 err = result.errors[0][1]
460 elif len(result.failures) == 1 and not result.errors:
461 err = result.failures[0][1]
462 else:
Fred Drake26641032001-10-04 19:46:07 +0000463 if testclass is None:
464 msg = "errors occurred; run in verbose mode for details"
465 else:
466 msg = "errors occurred in %s.%s" \
467 % (testclass.__module__, testclass.__name__)
468 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000469 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000470
Barry Warsawc10d6902001-09-20 06:30:41 +0000471
Walter Dörwald21d3a322003-05-01 17:45:56 +0000472def run_unittest(*classes):
473 """Run tests from unittest.TestCase-derived classes."""
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000474 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000475 for cls in classes:
Raymond Hettingerf3590622003-07-16 04:29:42 +0000476 if isinstance(cls, (unittest.TestSuite, unittest.TestCase)):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000477 suite.addTest(cls)
478 else:
479 suite.addTest(unittest.makeSuite(cls))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000480 if len(classes)==1:
481 testclass = classes[0]
482 else:
483 testclass = None
484 run_suite(suite, testclass)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000485
Barry Warsawc10d6902001-09-20 06:30:41 +0000486
Tim Petersa0a62222001-09-09 06:12:01 +0000487#=======================================================================
488# doctest driver.
489
490def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000491 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000492
493 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000494 test_support's belief about verbosity on to doctest. Else doctest's
495 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000496 """
497
498 import doctest
499
500 if verbosity is None:
501 verbosity = verbose
502 else:
503 verbosity = None
504
Tim Peters342ca752001-09-25 19:13:20 +0000505 # Direct doctest output (normally just errors) to real stdout; doctest
506 # output shouldn't be compared by regrtest.
507 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000508 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000509 try:
510 f, t = doctest.testmod(module, verbose=verbosity)
511 if f:
512 raise TestFailed("%d of %d doctests failed" % (f, t))
513 finally:
514 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000515 if verbose:
Raymond Hettinger1ba24b42003-05-17 01:59:57 +0000516 print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t)
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000517 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000518
519#=======================================================================
520# Threading support to prevent reporting refleaks when running regrtest.py -R
521
522def threading_setup():
523 import threading
524 return len(threading._active), len(threading._limbo)
525
526def threading_cleanup(num_active, num_limbo):
527 import threading
528 import time
529
530 _MAX_COUNT = 10
531 count = 0
532 while len(threading._active) != num_active and count < _MAX_COUNT:
533 count += 1
534 time.sleep(0.1)
535
536 count = 0
537 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
538 count += 1
539 time.sleep(0.1)
540
541def reap_children():
542 """Use this function at the end of test_main() whenever sub-processes
543 are started. This will help ensure that no extra children (zombies)
544 stick around to hog resources and create problems when looking
545 for refleaks.
546 """
547
548 # Reap all our dead child processes so we don't leave zombies around.
549 # These hog resources and might be causing some of the buildbots to die.
550 import os
551 if hasattr(os, 'waitpid'):
552 any_process = -1
553 while True:
554 try:
555 # This will raise an exception on Windows. That's ok.
556 pid, status = os.waitpid(any_process, os.WNOHANG)
557 if pid == 0:
558 break
559 except:
560 break