blob: 6cc52ea05b6e450b131995790cba81ad25bf0455 [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
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000109 print(' WARNING: failed to listen on port %d, trying another' % port, file=sys.__stderr__)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000110 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:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000180 print('WARNING: The filename %r CAN be encoded by the filesystem. ' \
Mark Hammond2e8624c2003-12-03 22:16:47 +0000181 'Unicode filename tests may not be effective' \
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000182 % TESTFN_UNICODE_UNENCODEABLE)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000183
184# Make sure we can write to TESTFN, try in /tmp if we can't
185fp = None
186try:
187 fp = open(TESTFN, 'w+')
188except IOError:
189 TMP_TESTFN = os.path.join('/tmp', TESTFN)
190 try:
191 fp = open(TMP_TESTFN, 'w+')
192 TESTFN = TMP_TESTFN
193 del TMP_TESTFN
194 except IOError:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000195 print(('WARNING: tests will fail, unable to write to: %s or %s' %
196 (TESTFN, TMP_TESTFN)))
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000197if fp is not None:
198 fp.close()
Neal Norwitz0e17f8c2006-01-23 07:51:27 +0000199 unlink(TESTFN)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000200del os, fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000201
Guido van Rossume26132c1998-04-23 20:13:30 +0000202def findfile(file, here=__file__):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000203 """Try to find a file on sys.path and the working directory. If it is not
204 found the argument passed to the function is returned (this does not
205 necessarily signal failure; could still be the legitimate path)."""
Fred Drake004d5e62000-10-23 17:22:08 +0000206 import os
207 if os.path.isabs(file):
208 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000209 path = sys.path
210 path = [os.path.dirname(here)] + path
211 for dn in path:
212 fn = os.path.join(dn, file)
213 if os.path.exists(fn): return fn
214 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000215
216def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000217 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000218
Skip Montanaroc955f892001-01-20 19:12:54 +0000219 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000220 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000221 """
Tim Peters983874d2001-01-19 05:59:21 +0000222
Tim Petersd2bf3b72001-01-18 02:22:22 +0000223 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000224 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000225
Tim Petersc2fe6182001-10-30 23:20:46 +0000226def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000227 """Raise TestFailed if a == b is false.
228
229 This is better than verify(a == b) because, in case of failure, the
230 error message incorporates repr(a) and repr(b) so you can see the
231 inputs.
232
233 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
234 former is tested.
235 """
236
Tim Petersc2fe6182001-10-30 23:20:46 +0000237 if not (a == b):
238 raise TestFailed, "%r == %r" % (a, b)
239
Tim Peters2f228e72001-05-13 00:19:31 +0000240def sortdict(dict):
241 "Like repr(dict), but in sorted order."
242 items = dict.items()
243 items.sort()
244 reprpairs = ["%r: %r" % pair for pair in items]
245 withcommas = ", ".join(reprpairs)
246 return "{%s}" % withcommas
247
Thomas Wouters89f507f2006-12-13 04:49:30 +0000248def check_syntax_error(testcase, statement):
Jeremy Hylton47793992001-02-19 15:35:26 +0000249 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000250 compile(statement, '<test string>', 'exec')
Jeremy Hylton47793992001-02-19 15:35:26 +0000251 except SyntaxError:
252 pass
253 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000254 testcase.fail('Missing SyntaxError: "%s"' % statement)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000255
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000256def open_urlresource(url):
257 import urllib, urlparse
258 import os.path
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000259
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000260 filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
261
262 for path in [os.path.curdir, os.path.pardir]:
263 fn = os.path.join(path, filename)
264 if os.path.exists(fn):
265 return open(fn)
266
267 requires('urlfetch')
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000268 print('\tfetching %s ...' % url, file=get_original_stdout())
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000269 fn, _ = urllib.urlretrieve(url, filename)
270 return open(fn)
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000271
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000272@contextmanager
273def guard_warnings_filter():
274 """Guard the warnings filter from being permanently changed."""
275 original_filters = warnings.filters[:]
276 try:
277 yield
278 finally:
279 warnings.filters = original_filters
280
281class EnvironmentVarGuard(object):
282
283 """Class to help protect the environment variable properly. Can be used as
284 a context manager."""
285
286 def __init__(self):
287 from os import environ
288 self._environ = environ
289 self._unset = set()
290 self._reset = dict()
291
292 def set(self, envvar, value):
293 if envvar not in self._environ:
294 self._unset.add(envvar)
295 else:
296 self._reset[envvar] = self._environ[envvar]
297 self._environ[envvar] = value
298
299 def unset(self, envvar):
300 if envvar in self._environ:
301 self._reset[envvar] = self._environ[envvar]
302 del self._environ[envvar]
303
304 def __enter__(self):
305 return self
306
307 def __exit__(self, *ignore_exc):
308 for envvar, value in self._reset.iteritems():
309 self._environ[envvar] = value
310 for unset in self._unset:
311 del self._environ[unset]
312
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000313
314#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000315# Decorator for running a function in a different locale, correctly resetting
316# it afterwards.
317
318def run_with_locale(catstr, *locales):
319 def decorator(func):
320 def inner(*args, **kwds):
321 try:
322 import locale
323 category = getattr(locale, catstr)
324 orig_locale = locale.setlocale(category)
325 except AttributeError:
326 # if the test author gives us an invalid category string
327 raise
328 except:
329 # cannot retrieve original locale, so do nothing
330 locale = orig_locale = None
331 else:
332 for loc in locales:
333 try:
334 locale.setlocale(category, loc)
335 break
336 except:
337 pass
338
339 # now run the function, resetting the locale on exceptions
340 try:
341 return func(*args, **kwds)
342 finally:
343 if locale and orig_locale:
344 locale.setlocale(category, orig_locale)
345 inner.func_name = func.func_name
346 inner.__doc__ = func.__doc__
347 return inner
348 return decorator
349
350#=======================================================================
351# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
352
353# Some handy shorthands. Note that these are used for byte-limits as well
354# as size-limits, in the various bigmem tests
355_1M = 1024*1024
356_1G = 1024 * _1M
357_2G = 2 * _1G
358
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000359# Hack to get at the maximum value an internal index can take.
360class _Dummy:
361 def __getslice__(self, i, j):
362 return j
363MAX_Py_ssize_t = _Dummy()[:]
364
Thomas Wouters477c8d52006-05-27 19:21:47 +0000365def set_memlimit(limit):
366 import re
367 global max_memuse
368 sizes = {
369 'k': 1024,
370 'm': _1M,
371 'g': _1G,
372 't': 1024*_1G,
373 }
374 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
375 re.IGNORECASE | re.VERBOSE)
376 if m is None:
377 raise ValueError('Invalid memory limit %r' % (limit,))
378 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000379 if memlimit > MAX_Py_ssize_t:
380 memlimit = MAX_Py_ssize_t
381 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000382 raise ValueError('Memory limit %r too low to be useful' % (limit,))
383 max_memuse = memlimit
384
385def bigmemtest(minsize, memuse, overhead=5*_1M):
386 """Decorator for bigmem tests.
387
388 'minsize' is the minimum useful size for the test (in arbitrary,
389 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
390 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
391 independant of the testsize, and defaults to 5Mb.
392
393 The decorator tries to guess a good value for 'size' and passes it to
394 the decorated test function. If minsize * memuse is more than the
395 allowed memory use (as defined by max_memuse), the test is skipped.
396 Otherwise, minsize is adjusted upward to use up to max_memuse.
397 """
398 def decorator(f):
399 def wrapper(self):
400 if not max_memuse:
401 # If max_memuse is 0 (the default),
402 # we still want to run the tests with size set to a few kb,
403 # to make sure they work. We still want to avoid using
404 # too much memory, though, but we do that noisily.
405 maxsize = 5147
406 self.failIf(maxsize * memuse + overhead > 20 * _1M)
407 else:
408 maxsize = int((max_memuse - overhead) / memuse)
409 if maxsize < minsize:
410 # Really ought to print 'test skipped' or something
411 if verbose:
412 sys.stderr.write("Skipping %s because of memory "
413 "constraint\n" % (f.__name__,))
414 return
415 # Try to keep some breathing room in memory use
416 maxsize = max(maxsize - 50 * _1M, minsize)
417 return f(self, maxsize)
418 wrapper.minsize = minsize
419 wrapper.memuse = memuse
420 wrapper.overhead = overhead
421 return wrapper
422 return decorator
423
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000424def bigaddrspacetest(f):
425 """Decorator for tests that fill the address space."""
426 def wrapper(self):
427 if max_memuse < MAX_Py_ssize_t:
428 if verbose:
429 sys.stderr.write("Skipping %s because of memory "
430 "constraint\n" % (f.__name__,))
431 else:
432 return f(self)
433 return wrapper
434
Thomas Wouters477c8d52006-05-27 19:21:47 +0000435#=======================================================================
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000436# Preliminary PyUNIT integration.
437
438import unittest
439
440
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000441class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000442 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000443 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000444 test(result)
445 return result
446
447
Fred Drake26641032001-10-04 19:46:07 +0000448def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000449 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000450 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000451 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000452 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000453 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000454
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000455 result = runner.run(suite)
456 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000457 if len(result.errors) == 1 and not result.failures:
458 err = result.errors[0][1]
459 elif len(result.failures) == 1 and not result.errors:
460 err = result.failures[0][1]
461 else:
Fred Drake26641032001-10-04 19:46:07 +0000462 if testclass is None:
463 msg = "errors occurred; run in verbose mode for details"
464 else:
465 msg = "errors occurred in %s.%s" \
466 % (testclass.__module__, testclass.__name__)
467 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000468 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000469
Barry Warsawc10d6902001-09-20 06:30:41 +0000470
Walter Dörwald21d3a322003-05-01 17:45:56 +0000471def run_unittest(*classes):
472 """Run tests from unittest.TestCase-derived classes."""
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000473 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000474 for cls in classes:
Raymond Hettingerf3590622003-07-16 04:29:42 +0000475 if isinstance(cls, (unittest.TestSuite, unittest.TestCase)):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000476 suite.addTest(cls)
477 else:
478 suite.addTest(unittest.makeSuite(cls))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000479 if len(classes)==1:
480 testclass = classes[0]
481 else:
482 testclass = None
483 run_suite(suite, testclass)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000484
Barry Warsawc10d6902001-09-20 06:30:41 +0000485
Tim Petersa0a62222001-09-09 06:12:01 +0000486#=======================================================================
487# doctest driver.
488
489def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000490 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000491
492 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000493 test_support's belief about verbosity on to doctest. Else doctest's
494 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000495 """
496
497 import doctest
498
499 if verbosity is None:
500 verbosity = verbose
501 else:
502 verbosity = None
503
Tim Peters342ca752001-09-25 19:13:20 +0000504 # Direct doctest output (normally just errors) to real stdout; doctest
505 # output shouldn't be compared by regrtest.
506 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000507 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000508 try:
509 f, t = doctest.testmod(module, verbose=verbosity)
510 if f:
511 raise TestFailed("%d of %d doctests failed" % (f, t))
512 finally:
513 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000514 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000515 print('doctest (%s) ... %d tests with zero failures' % (module.__name__, t))
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000516 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000517
518#=======================================================================
519# Threading support to prevent reporting refleaks when running regrtest.py -R
520
521def threading_setup():
522 import threading
523 return len(threading._active), len(threading._limbo)
524
525def threading_cleanup(num_active, num_limbo):
526 import threading
527 import time
528
529 _MAX_COUNT = 10
530 count = 0
531 while len(threading._active) != num_active and count < _MAX_COUNT:
532 count += 1
533 time.sleep(0.1)
534
535 count = 0
536 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
537 count += 1
538 time.sleep(0.1)
539
540def reap_children():
541 """Use this function at the end of test_main() whenever sub-processes
542 are started. This will help ensure that no extra children (zombies)
543 stick around to hog resources and create problems when looking
544 for refleaks.
545 """
546
547 # Reap all our dead child processes so we don't leave zombies around.
548 # These hog resources and might be causing some of the buildbots to die.
549 import os
550 if hasattr(os, 'waitpid'):
551 any_process = -1
552 while True:
553 try:
554 # This will raise an exception on Windows. That's ok.
555 pid, status = os.waitpid(any_process, os.WNOHANG)
556 if pid == 0:
557 break
558 except:
559 break