blob: 6fbb3ccabfad42e924d63424b35aa05bb8be5185 [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."
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000242 items = sorted(dict.items())
Tim Peters2f228e72001-05-13 00:19:31 +0000243 reprpairs = ["%r: %r" % pair for pair in items]
244 withcommas = ", ".join(reprpairs)
245 return "{%s}" % withcommas
246
Thomas Wouters89f507f2006-12-13 04:49:30 +0000247def check_syntax_error(testcase, statement):
Jeremy Hylton47793992001-02-19 15:35:26 +0000248 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000249 compile(statement, '<test string>', 'exec')
Jeremy Hylton47793992001-02-19 15:35:26 +0000250 except SyntaxError:
251 pass
252 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000253 testcase.fail('Missing SyntaxError: "%s"' % statement)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000254
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000255def open_urlresource(url):
256 import urllib, urlparse
257 import os.path
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000258
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000259 filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
260
261 for path in [os.path.curdir, os.path.pardir]:
262 fn = os.path.join(path, filename)
263 if os.path.exists(fn):
264 return open(fn)
265
266 requires('urlfetch')
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000267 print('\tfetching %s ...' % url, file=get_original_stdout())
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000268 fn, _ = urllib.urlretrieve(url, filename)
269 return open(fn)
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000270
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000271@contextmanager
272def guard_warnings_filter():
273 """Guard the warnings filter from being permanently changed."""
274 original_filters = warnings.filters[:]
275 try:
276 yield
277 finally:
278 warnings.filters = original_filters
279
280class EnvironmentVarGuard(object):
281
282 """Class to help protect the environment variable properly. Can be used as
283 a context manager."""
284
285 def __init__(self):
286 from os import environ
287 self._environ = environ
288 self._unset = set()
289 self._reset = dict()
290
291 def set(self, envvar, value):
292 if envvar not in self._environ:
293 self._unset.add(envvar)
294 else:
295 self._reset[envvar] = self._environ[envvar]
296 self._environ[envvar] = value
297
298 def unset(self, envvar):
299 if envvar in self._environ:
300 self._reset[envvar] = self._environ[envvar]
301 del self._environ[envvar]
302
303 def __enter__(self):
304 return self
305
306 def __exit__(self, *ignore_exc):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000307 for envvar, value in self._reset.items():
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000308 self._environ[envvar] = value
309 for unset in self._unset:
310 del self._environ[unset]
311
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000312
313#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000314# Decorator for running a function in a different locale, correctly resetting
315# it afterwards.
316
317def run_with_locale(catstr, *locales):
318 def decorator(func):
319 def inner(*args, **kwds):
320 try:
321 import locale
322 category = getattr(locale, catstr)
323 orig_locale = locale.setlocale(category)
324 except AttributeError:
325 # if the test author gives us an invalid category string
326 raise
327 except:
328 # cannot retrieve original locale, so do nothing
329 locale = orig_locale = None
330 else:
331 for loc in locales:
332 try:
333 locale.setlocale(category, loc)
334 break
335 except:
336 pass
337
338 # now run the function, resetting the locale on exceptions
339 try:
340 return func(*args, **kwds)
341 finally:
342 if locale and orig_locale:
343 locale.setlocale(category, orig_locale)
Neal Norwitz221085d2007-02-25 20:55:47 +0000344 inner.__name__ = func.__name__
Thomas Wouters477c8d52006-05-27 19:21:47 +0000345 inner.__doc__ = func.__doc__
346 return inner
347 return decorator
348
349#=======================================================================
350# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
351
352# Some handy shorthands. Note that these are used for byte-limits as well
353# as size-limits, in the various bigmem tests
354_1M = 1024*1024
355_1G = 1024 * _1M
356_2G = 2 * _1G
357
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000358# Hack to get at the maximum value an internal index can take.
359class _Dummy:
360 def __getslice__(self, i, j):
361 return j
362MAX_Py_ssize_t = _Dummy()[:]
363
Thomas Wouters477c8d52006-05-27 19:21:47 +0000364def set_memlimit(limit):
365 import re
366 global max_memuse
367 sizes = {
368 'k': 1024,
369 'm': _1M,
370 'g': _1G,
371 't': 1024*_1G,
372 }
373 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
374 re.IGNORECASE | re.VERBOSE)
375 if m is None:
376 raise ValueError('Invalid memory limit %r' % (limit,))
377 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000378 if memlimit > MAX_Py_ssize_t:
379 memlimit = MAX_Py_ssize_t
380 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000381 raise ValueError('Memory limit %r too low to be useful' % (limit,))
382 max_memuse = memlimit
383
384def bigmemtest(minsize, memuse, overhead=5*_1M):
385 """Decorator for bigmem tests.
386
387 'minsize' is the minimum useful size for the test (in arbitrary,
388 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
389 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
390 independant of the testsize, and defaults to 5Mb.
391
392 The decorator tries to guess a good value for 'size' and passes it to
393 the decorated test function. If minsize * memuse is more than the
394 allowed memory use (as defined by max_memuse), the test is skipped.
395 Otherwise, minsize is adjusted upward to use up to max_memuse.
396 """
397 def decorator(f):
398 def wrapper(self):
399 if not max_memuse:
400 # If max_memuse is 0 (the default),
401 # we still want to run the tests with size set to a few kb,
402 # to make sure they work. We still want to avoid using
403 # too much memory, though, but we do that noisily.
404 maxsize = 5147
405 self.failIf(maxsize * memuse + overhead > 20 * _1M)
406 else:
407 maxsize = int((max_memuse - overhead) / memuse)
408 if maxsize < minsize:
409 # Really ought to print 'test skipped' or something
410 if verbose:
411 sys.stderr.write("Skipping %s because of memory "
412 "constraint\n" % (f.__name__,))
413 return
414 # Try to keep some breathing room in memory use
415 maxsize = max(maxsize - 50 * _1M, minsize)
416 return f(self, maxsize)
417 wrapper.minsize = minsize
418 wrapper.memuse = memuse
419 wrapper.overhead = overhead
420 return wrapper
421 return decorator
422
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000423def bigaddrspacetest(f):
424 """Decorator for tests that fill the address space."""
425 def wrapper(self):
426 if max_memuse < MAX_Py_ssize_t:
427 if verbose:
428 sys.stderr.write("Skipping %s because of memory "
429 "constraint\n" % (f.__name__,))
430 else:
431 return f(self)
432 return wrapper
433
Thomas Wouters477c8d52006-05-27 19:21:47 +0000434#=======================================================================
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000435# Preliminary PyUNIT integration.
436
437import unittest
438
439
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000440class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000441 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000442 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000443 test(result)
444 return result
445
446
Fred Drake26641032001-10-04 19:46:07 +0000447def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000448 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000449 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000450 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000451 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000452 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000453
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000454 result = runner.run(suite)
455 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000456 if len(result.errors) == 1 and not result.failures:
457 err = result.errors[0][1]
458 elif len(result.failures) == 1 and not result.errors:
459 err = result.failures[0][1]
460 else:
Fred Drake26641032001-10-04 19:46:07 +0000461 if testclass is None:
462 msg = "errors occurred; run in verbose mode for details"
463 else:
464 msg = "errors occurred in %s.%s" \
465 % (testclass.__module__, testclass.__name__)
466 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000467 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000468
Barry Warsawc10d6902001-09-20 06:30:41 +0000469
Walter Dörwald21d3a322003-05-01 17:45:56 +0000470def run_unittest(*classes):
471 """Run tests from unittest.TestCase-derived classes."""
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000472 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000473 for cls in classes:
Raymond Hettingerf3590622003-07-16 04:29:42 +0000474 if isinstance(cls, (unittest.TestSuite, unittest.TestCase)):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000475 suite.addTest(cls)
476 else:
477 suite.addTest(unittest.makeSuite(cls))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000478 if len(classes)==1:
479 testclass = classes[0]
480 else:
481 testclass = None
482 run_suite(suite, testclass)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000483
Barry Warsawc10d6902001-09-20 06:30:41 +0000484
Tim Petersa0a62222001-09-09 06:12:01 +0000485#=======================================================================
486# doctest driver.
487
488def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000489 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000490
491 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000492 test_support's belief about verbosity on to doctest. Else doctest's
493 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000494 """
495
496 import doctest
497
498 if verbosity is None:
499 verbosity = verbose
500 else:
501 verbosity = None
502
Tim Peters342ca752001-09-25 19:13:20 +0000503 # Direct doctest output (normally just errors) to real stdout; doctest
504 # output shouldn't be compared by regrtest.
505 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000506 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000507 try:
508 f, t = doctest.testmod(module, verbose=verbosity)
509 if f:
510 raise TestFailed("%d of %d doctests failed" % (f, t))
511 finally:
512 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000513 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000514 print('doctest (%s) ... %d tests with zero failures' % (module.__name__, t))
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000515 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000516
517#=======================================================================
518# Threading support to prevent reporting refleaks when running regrtest.py -R
519
520def threading_setup():
521 import threading
522 return len(threading._active), len(threading._limbo)
523
524def threading_cleanup(num_active, num_limbo):
525 import threading
526 import time
527
528 _MAX_COUNT = 10
529 count = 0
530 while len(threading._active) != num_active and count < _MAX_COUNT:
531 count += 1
532 time.sleep(0.1)
533
534 count = 0
535 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
536 count += 1
537 time.sleep(0.1)
538
539def reap_children():
540 """Use this function at the end of test_main() whenever sub-processes
541 are started. This will help ensure that no extra children (zombies)
542 stick around to hog resources and create problems when looking
543 for refleaks.
544 """
545
546 # Reap all our dead child processes so we don't leave zombies around.
547 # These hog resources and might be causing some of the buildbots to die.
548 import os
549 if hasattr(os, 'waitpid'):
550 any_process = -1
551 while True:
552 try:
553 # This will raise an exception on Windows. That's ok.
554 pid, status = os.waitpid(any_process, os.WNOHANG)
555 if pid == 0:
556 break
557 except:
558 break