blob: 6a1fa86785cbfa3d3bdbf656adbfa7fd108d4bd4 [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':
Guido van Rossumd8faa362007-04-27 19:54:29 +00004 raise ImportError('test_support must be imported from the test package')
Barry Warsaw408b6d32002-07-30 23:27:12 +00005
Guido van Rossumd8faa362007-04-27 19:54:29 +00006import contextlib
7import errno
8import socket
Fred Drakecd1b1dd2001-03-21 18:26:33 +00009import sys
Guido van Rossumd8faa362007-04-27 19:54:29 +000010import os
11import os.path
Thomas Wouters902d6eb2007-01-09 23:18:33 +000012import warnings
Guido van Rossumd8faa362007-04-27 19:54:29 +000013import types
14import unittest
Fred Drakecd1b1dd2001-03-21 18:26:33 +000015
Fred Drake1790dd42000-07-24 06:55:00 +000016class Error(Exception):
Fred Drake004d5e62000-10-23 17:22:08 +000017 """Base class for regression test exceptions."""
Fred Drake1790dd42000-07-24 06:55:00 +000018
19class TestFailed(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000020 """Test failed."""
Fred Drake1790dd42000-07-24 06:55:00 +000021
22class TestSkipped(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000023 """Test skipped.
Fred Drake1790dd42000-07-24 06:55:00 +000024
Fred Drake004d5e62000-10-23 17:22:08 +000025 This can be raised to indicate that a test was deliberatly
26 skipped, but not because a feature wasn't available. For
27 example, if some resource can't be used, such as the network
28 appears to be unavailable, this should be raised instead of
29 TestFailed.
Fred Drake004d5e62000-10-23 17:22:08 +000030 """
Fred Drake1790dd42000-07-24 06:55:00 +000031
Fred Drake9a0db072003-02-03 15:19:30 +000032class ResourceDenied(TestSkipped):
33 """Test skipped because it requested a disallowed resource.
34
35 This is raised when a test calls requires() for a resource that
36 has not be enabled. It is used to distinguish between expected
37 and unexpected skips.
38 """
39
Barry Warsawc0fb6052001-08-20 22:29:23 +000040verbose = 1 # Flag set to 0 by regrtest.py
Thomas Wouters477c8d52006-05-27 19:21:47 +000041use_resources = None # Flag set to [] by regrtest.py
42max_memuse = 0 # Disable bigmem tests (they will still be run with
43 # small sizes, to make sure they work.)
Guido van Rossum531661c1996-12-20 02:58:22 +000044
Tim Peters8dee8092001-09-25 20:05:11 +000045# _original_stdout is meant to hold stdout at the time regrtest began.
46# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
47# The point is to have some flavor of stdout the user can actually see.
48_original_stdout = None
49def record_original_stdout(stdout):
50 global _original_stdout
51 _original_stdout = stdout
52
53def get_original_stdout():
54 return _original_stdout or sys.stdout
55
Guido van Rossum3bead091992-01-27 17:00:37 +000056def unload(name):
Fred Drake004d5e62000-10-23 17:22:08 +000057 try:
58 del sys.modules[name]
59 except KeyError:
60 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000061
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000062def unlink(filename):
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000063 try:
64 os.unlink(filename)
65 except OSError:
66 pass
67
Guido van Rossum3bead091992-01-27 17:00:37 +000068def forget(modname):
Brett Cannonf1cfb622003-05-04 21:15:27 +000069 '''"Forget" a module was ever imported by removing it from sys.modules and
70 deleting any .pyc and .pyo files.'''
Fred Drake004d5e62000-10-23 17:22:08 +000071 unload(modname)
Fred Drake004d5e62000-10-23 17:22:08 +000072 for dirname in sys.path:
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000073 unlink(os.path.join(dirname, modname + os.extsep + 'pyc'))
Brett Cannonf1cfb622003-05-04 21:15:27 +000074 # Deleting the .pyo file cannot be within the 'try' for the .pyc since
75 # the chance exists that there is no .pyc (and thus the 'try' statement
76 # is exited) but there is a .pyo file.
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000077 unlink(os.path.join(dirname, modname + os.extsep + 'pyo'))
Guido van Rossum3bead091992-01-27 17:00:37 +000078
Tim Petersb4ee4eb2002-12-04 03:26:57 +000079def is_resource_enabled(resource):
Brett Cannonf1cfb622003-05-04 21:15:27 +000080 """Test whether a resource is enabled. Known resources are set by
81 regrtest.py."""
Tim Petersb4ee4eb2002-12-04 03:26:57 +000082 return use_resources is not None and resource in use_resources
83
Barry Warsawc0fb6052001-08-20 22:29:23 +000084def requires(resource, msg=None):
Brett Cannonf1cfb622003-05-04 21:15:27 +000085 """Raise ResourceDenied if the specified resource is not available.
86
87 If the caller's module is __main__ then automatically return True. The
88 possibility of False being returned occurs when regrtest.py is executing."""
Skip Montanarod839ecd2003-04-24 19:06:57 +000089 # see if the caller's module is __main__ - if so, treat as if
90 # the resource was set
91 if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
92 return
Tim Petersb4ee4eb2002-12-04 03:26:57 +000093 if not is_resource_enabled(resource):
Barry Warsawc0fb6052001-08-20 22:29:23 +000094 if msg is None:
95 msg = "Use of the `%s' resource not enabled" % resource
Fred Drake9a0db072003-02-03 15:19:30 +000096 raise ResourceDenied(msg)
Barry Warsawc0fb6052001-08-20 22:29:23 +000097
Thomas Wouters0e3f5912006-08-11 14:57:12 +000098def bind_port(sock, host='', preferred_port=54321):
99 """Try to bind the sock to a port. If we are running multiple
100 tests and we don't try multiple ports, the test can fails. This
101 makes the test more robust."""
102
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000103 # some random ports that hopefully no one is listening on.
104 for port in [preferred_port, 9907, 10243, 32999]:
105 try:
106 sock.bind((host, port))
107 return port
Guido van Rossumb940e112007-01-10 16:19:56 +0000108 except socket.error as e:
Guido van Rossume2c8f2d2007-05-09 23:43:17 +0000109 (err, msg) = e.args
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000110 if err != errno.EADDRINUSE:
111 raise
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000112 print(' WARNING: failed to listen on port %d, trying another' % port, file=sys.__stderr__)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000113 raise TestFailed('unable to find port to listen on')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000114
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000115FUZZ = 1e-6
116
117def fcmp(x, y): # fuzzy comparison function
Neal Norwitz79212992006-08-21 16:27:31 +0000118 if isinstance(x, float) or isinstance(y, float):
Fred Drake004d5e62000-10-23 17:22:08 +0000119 try:
Fred Drake004d5e62000-10-23 17:22:08 +0000120 fuzz = (abs(x) + abs(y)) * FUZZ
121 if abs(x-y) <= fuzz:
122 return 0
123 except:
124 pass
Neal Norwitz79212992006-08-21 16:27:31 +0000125 elif type(x) == type(y) and isinstance(x, (tuple, list)):
Fred Drake004d5e62000-10-23 17:22:08 +0000126 for i in range(min(len(x), len(y))):
127 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +0000128 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +0000129 return outcome
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000130 return (len(x) > len(y)) - (len(x) < len(y))
131 return (x > y) - (x < y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000132
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000133try:
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000134 str
Neal Norwitz79212992006-08-21 16:27:31 +0000135 have_unicode = True
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000136except NameError:
Neal Norwitz79212992006-08-21 16:27:31 +0000137 have_unicode = False
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000138
Finn Bock57bc5fa2002-11-01 18:02:03 +0000139is_jython = sys.platform.startswith('java')
140
Barry Warsaw559f6682001-03-23 18:04:02 +0000141# Filename used for testing
142if os.name == 'java':
143 # Jython disallows @ in module names
144 TESTFN = '$test'
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000145elif os.name == 'riscos':
146 TESTFN = 'testfile'
147else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000148 TESTFN = '@test'
Walter Dörwald9b775532007-06-08 14:30:53 +0000149
150 # 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
153 TESTFN_UNICODE = "@test-\xe0\xf2"
154 TESTFN_ENCODING = sys.getfilesystemencoding()
155 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
156 # able to be encoded by *either* the default or filesystem encoding.
157 # This test really only makes sense on Windows NT platforms
158 # which have special Unicode support in posixmodule.
159 if (not hasattr(sys, "getwindowsversion") or
160 sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
161 TESTFN_UNICODE_UNENCODEABLE = None
162 else:
163 # Japanese characters (I think - from bug 846133)
164 TESTFN_UNICODE_UNENCODEABLE = "@test-\u5171\u6709\u3055\u308c\u308b"
165 try:
166 # XXX - Note - should be using TESTFN_ENCODING here - but for
167 # Windows, "mbcs" currently always operates as if in
168 # errors=ignore' mode - hence we get '?' characters rather than
169 # the exception. 'Latin1' operates as we expect - ie, fails.
170 # See [ 850997 ] mbcs encoding ignores errors
171 TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
172 except UnicodeEncodeError:
173 pass
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000174 else:
Walter Dörwald9b775532007-06-08 14:30:53 +0000175 print('WARNING: The filename %r CAN be encoded by the filesystem. ' \
176 'Unicode filename tests may not be effective' \
177 % TESTFN_UNICODE_UNENCODEABLE)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000178
179# Make sure we can write to TESTFN, try in /tmp if we can't
180fp = None
181try:
182 fp = open(TESTFN, 'w+')
183except IOError:
184 TMP_TESTFN = os.path.join('/tmp', TESTFN)
185 try:
186 fp = open(TMP_TESTFN, 'w+')
187 TESTFN = TMP_TESTFN
188 del TMP_TESTFN
189 except IOError:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000190 print(('WARNING: tests will fail, unable to write to: %s or %s' %
191 (TESTFN, TMP_TESTFN)))
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000192if fp is not None:
193 fp.close()
Neal Norwitz0e17f8c2006-01-23 07:51:27 +0000194 unlink(TESTFN)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000195del fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000196
Guido van Rossume26132c1998-04-23 20:13:30 +0000197def findfile(file, here=__file__):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000198 """Try to find a file on sys.path and the working directory. If it is not
199 found the argument passed to the function is returned (this does not
200 necessarily signal failure; could still be the legitimate path)."""
Fred Drake004d5e62000-10-23 17:22:08 +0000201 if os.path.isabs(file):
202 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000203 path = sys.path
204 path = [os.path.dirname(here)] + path
205 for dn in path:
206 fn = os.path.join(dn, file)
207 if os.path.exists(fn): return fn
208 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000209
210def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000211 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000212
Skip Montanaroc955f892001-01-20 19:12:54 +0000213 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000214 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000215 """
Tim Peters983874d2001-01-19 05:59:21 +0000216
Tim Petersd2bf3b72001-01-18 02:22:22 +0000217 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000218 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000219
Tim Petersc2fe6182001-10-30 23:20:46 +0000220def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000221 """Raise TestFailed if a == b is false.
222
223 This is better than verify(a == b) because, in case of failure, the
224 error message incorporates repr(a) and repr(b) so you can see the
225 inputs.
226
227 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
228 former is tested.
229 """
230
Tim Petersc2fe6182001-10-30 23:20:46 +0000231 if not (a == b):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000232 raise TestFailed("%r == %r" % (a, b))
Tim Petersc2fe6182001-10-30 23:20:46 +0000233
Tim Peters2f228e72001-05-13 00:19:31 +0000234def sortdict(dict):
235 "Like repr(dict), but in sorted order."
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000236 items = sorted(dict.items())
Tim Peters2f228e72001-05-13 00:19:31 +0000237 reprpairs = ["%r: %r" % pair for pair in items]
238 withcommas = ", ".join(reprpairs)
239 return "{%s}" % withcommas
240
Thomas Wouters89f507f2006-12-13 04:49:30 +0000241def check_syntax_error(testcase, statement):
Jeremy Hylton47793992001-02-19 15:35:26 +0000242 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000243 compile(statement, '<test string>', 'exec')
Jeremy Hylton47793992001-02-19 15:35:26 +0000244 except SyntaxError:
245 pass
246 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000247 testcase.fail('Missing SyntaxError: "%s"' % statement)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000248
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000249def open_urlresource(url):
250 import urllib, urlparse
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000251
Guido van Rossum360e4b82007-05-14 22:51:27 +0000252 requires('urlfetch')
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000253 filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
254
255 for path in [os.path.curdir, os.path.pardir]:
256 fn = os.path.join(path, filename)
257 if os.path.exists(fn):
258 return open(fn)
259
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000260 print('\tfetching %s ...' % url, file=get_original_stdout())
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000261 fn, _ = urllib.urlretrieve(url, filename)
262 return open(fn)
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000263
Guido van Rossumd8faa362007-04-27 19:54:29 +0000264@contextlib.contextmanager
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000265def guard_warnings_filter():
266 """Guard the warnings filter from being permanently changed."""
267 original_filters = warnings.filters[:]
268 try:
269 yield
270 finally:
271 warnings.filters = original_filters
272
Guido van Rossumd8faa362007-04-27 19:54:29 +0000273class WarningMessage(object):
274 "Holds the result of the latest showwarning() call"
275 def __init__(self):
276 self.message = None
277 self.category = None
278 self.filename = None
279 self.lineno = None
280
281 def _showwarning(self, message, category, filename, lineno, file=None):
282 self.message = message
283 self.category = category
284 self.filename = filename
285 self.lineno = lineno
286
287@contextlib.contextmanager
288def catch_warning():
289 """
290 Guard the warnings filter from being permanently changed and record the
291 data of the last warning that has been issued.
292
293 Use like this:
294
295 with catch_warning as w:
296 warnings.warn("foo")
297 assert str(w.message) == "foo"
298 """
299 warning = WarningMessage()
300 original_filters = warnings.filters[:]
301 original_showwarning = warnings.showwarning
302 warnings.showwarning = warning._showwarning
303 try:
304 yield warning
305 finally:
306 warnings.showwarning = original_showwarning
307 warnings.filters = original_filters
308
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000309class EnvironmentVarGuard(object):
310
311 """Class to help protect the environment variable properly. Can be used as
312 a context manager."""
313
314 def __init__(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000315 self._environ = os.environ
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000316 self._unset = set()
317 self._reset = dict()
318
319 def set(self, envvar, value):
320 if envvar not in self._environ:
321 self._unset.add(envvar)
322 else:
323 self._reset[envvar] = self._environ[envvar]
324 self._environ[envvar] = value
325
326 def unset(self, envvar):
327 if envvar in self._environ:
328 self._reset[envvar] = self._environ[envvar]
329 del self._environ[envvar]
330
331 def __enter__(self):
332 return self
333
334 def __exit__(self, *ignore_exc):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000335 for envvar, value in self._reset.items():
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000336 self._environ[envvar] = value
337 for unset in self._unset:
338 del self._environ[unset]
339
Guido van Rossumd8faa362007-04-27 19:54:29 +0000340class TransientResource(object):
341
342 """Raise ResourceDenied if an exception is raised while the context manager
343 is in effect that matches the specified exception and attributes."""
344
345 def __init__(self, exc, **kwargs):
346 self.exc = exc
347 self.attrs = kwargs
348
349 def __enter__(self):
350 return self
351
352 def __exit__(self, type_=None, value=None, traceback=None):
353 """If type_ is a subclass of self.exc and value has attributes matching
354 self.attrs, raise ResourceDenied. Otherwise let the exception
355 propagate (if any)."""
356 if type_ is not None and issubclass(self.exc, type_):
357 for attr, attr_value in self.attrs.items():
358 if not hasattr(value, attr):
359 break
360 if getattr(value, attr) != attr_value:
361 break
362 else:
363 raise ResourceDenied("an optional resource is not available")
364
365
366def transient_internet():
367 """Return a context manager that raises ResourceDenied when various issues
368 with the Internet connection manifest themselves as exceptions."""
369 time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
370 socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
371 ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
372 return contextlib.nested(time_out, socket_peer_reset, ioerror_peer_reset)
373
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000374
375#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000376# Decorator for running a function in a different locale, correctly resetting
377# it afterwards.
378
379def run_with_locale(catstr, *locales):
380 def decorator(func):
381 def inner(*args, **kwds):
382 try:
383 import locale
384 category = getattr(locale, catstr)
385 orig_locale = locale.setlocale(category)
386 except AttributeError:
387 # if the test author gives us an invalid category string
388 raise
389 except:
390 # cannot retrieve original locale, so do nothing
391 locale = orig_locale = None
392 else:
393 for loc in locales:
394 try:
395 locale.setlocale(category, loc)
396 break
397 except:
398 pass
399
400 # now run the function, resetting the locale on exceptions
401 try:
402 return func(*args, **kwds)
403 finally:
404 if locale and orig_locale:
405 locale.setlocale(category, orig_locale)
Neal Norwitz221085d2007-02-25 20:55:47 +0000406 inner.__name__ = func.__name__
Thomas Wouters477c8d52006-05-27 19:21:47 +0000407 inner.__doc__ = func.__doc__
408 return inner
409 return decorator
410
411#=======================================================================
412# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
413
414# Some handy shorthands. Note that these are used for byte-limits as well
415# as size-limits, in the various bigmem tests
416_1M = 1024*1024
417_1G = 1024 * _1M
418_2G = 2 * _1G
419
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000420# Hack to get at the maximum value an internal index can take.
421class _Dummy:
422 def __getslice__(self, i, j):
423 return j
424MAX_Py_ssize_t = _Dummy()[:]
425
Thomas Wouters477c8d52006-05-27 19:21:47 +0000426def set_memlimit(limit):
427 import re
428 global max_memuse
429 sizes = {
430 'k': 1024,
431 'm': _1M,
432 'g': _1G,
433 't': 1024*_1G,
434 }
435 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
436 re.IGNORECASE | re.VERBOSE)
437 if m is None:
438 raise ValueError('Invalid memory limit %r' % (limit,))
439 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000440 if memlimit > MAX_Py_ssize_t:
441 memlimit = MAX_Py_ssize_t
442 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443 raise ValueError('Memory limit %r too low to be useful' % (limit,))
444 max_memuse = memlimit
445
446def bigmemtest(minsize, memuse, overhead=5*_1M):
447 """Decorator for bigmem tests.
448
449 'minsize' is the minimum useful size for the test (in arbitrary,
450 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
451 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
452 independant of the testsize, and defaults to 5Mb.
453
454 The decorator tries to guess a good value for 'size' and passes it to
455 the decorated test function. If minsize * memuse is more than the
456 allowed memory use (as defined by max_memuse), the test is skipped.
457 Otherwise, minsize is adjusted upward to use up to max_memuse.
458 """
459 def decorator(f):
460 def wrapper(self):
461 if not max_memuse:
462 # If max_memuse is 0 (the default),
463 # we still want to run the tests with size set to a few kb,
464 # to make sure they work. We still want to avoid using
465 # too much memory, though, but we do that noisily.
466 maxsize = 5147
467 self.failIf(maxsize * memuse + overhead > 20 * _1M)
468 else:
469 maxsize = int((max_memuse - overhead) / memuse)
470 if maxsize < minsize:
471 # Really ought to print 'test skipped' or something
472 if verbose:
473 sys.stderr.write("Skipping %s because of memory "
474 "constraint\n" % (f.__name__,))
475 return
476 # Try to keep some breathing room in memory use
477 maxsize = max(maxsize - 50 * _1M, minsize)
478 return f(self, maxsize)
479 wrapper.minsize = minsize
480 wrapper.memuse = memuse
481 wrapper.overhead = overhead
482 return wrapper
483 return decorator
484
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000485def bigaddrspacetest(f):
486 """Decorator for tests that fill the address space."""
487 def wrapper(self):
488 if max_memuse < MAX_Py_ssize_t:
489 if verbose:
490 sys.stderr.write("Skipping %s because of memory "
491 "constraint\n" % (f.__name__,))
492 else:
493 return f(self)
494 return wrapper
495
Thomas Wouters477c8d52006-05-27 19:21:47 +0000496#=======================================================================
Guido van Rossumd8faa362007-04-27 19:54:29 +0000497# unittest integration.
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000498
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000499class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000500 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000501 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000502 test(result)
503 return result
504
505
Guido van Rossumd8faa362007-04-27 19:54:29 +0000506def _run_suite(suite):
Barry Warsawc88425e2001-09-20 06:31:22 +0000507 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000508 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000509 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000510 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000511 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000512
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000513 result = runner.run(suite)
514 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000515 if len(result.errors) == 1 and not result.failures:
516 err = result.errors[0][1]
517 elif len(result.failures) == 1 and not result.errors:
518 err = result.failures[0][1]
519 else:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000520 msg = "errors occurred; run in verbose mode for details"
Fred Drake26641032001-10-04 19:46:07 +0000521 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000522 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000523
Barry Warsawc10d6902001-09-20 06:30:41 +0000524
Walter Dörwald21d3a322003-05-01 17:45:56 +0000525def run_unittest(*classes):
526 """Run tests from unittest.TestCase-derived classes."""
Guido van Rossumd8faa362007-04-27 19:54:29 +0000527 valid_types = (unittest.TestSuite, unittest.TestCase)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000528 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000529 for cls in classes:
Walter Dörwaldbf58bd62007-05-04 07:18:10 +0000530 if isinstance(cls, basestring):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000531 if cls in sys.modules:
532 suite.addTest(unittest.findTestCases(sys.modules[cls]))
533 else:
534 raise ValueError("str arguments must be keys in sys.modules")
535 elif isinstance(cls, valid_types):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000536 suite.addTest(cls)
537 else:
538 suite.addTest(unittest.makeSuite(cls))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000539 _run_suite(suite)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000540
Barry Warsawc10d6902001-09-20 06:30:41 +0000541
Tim Petersa0a62222001-09-09 06:12:01 +0000542#=======================================================================
543# doctest driver.
544
545def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000546 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000547
548 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000549 test_support's belief about verbosity on to doctest. Else doctest's
550 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000551 """
552
553 import doctest
554
555 if verbosity is None:
556 verbosity = verbose
557 else:
558 verbosity = None
559
Tim Peters342ca752001-09-25 19:13:20 +0000560 # Direct doctest output (normally just errors) to real stdout; doctest
561 # output shouldn't be compared by regrtest.
562 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000563 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000564 try:
565 f, t = doctest.testmod(module, verbose=verbosity)
566 if f:
567 raise TestFailed("%d of %d doctests failed" % (f, t))
568 finally:
569 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000570 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000571 print('doctest (%s) ... %d tests with zero failures' % (module.__name__, t))
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000572 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000573
574#=======================================================================
575# Threading support to prevent reporting refleaks when running regrtest.py -R
576
577def threading_setup():
578 import threading
579 return len(threading._active), len(threading._limbo)
580
581def threading_cleanup(num_active, num_limbo):
582 import threading
583 import time
584
585 _MAX_COUNT = 10
586 count = 0
587 while len(threading._active) != num_active and count < _MAX_COUNT:
588 count += 1
589 time.sleep(0.1)
590
591 count = 0
592 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
593 count += 1
594 time.sleep(0.1)
595
596def reap_children():
597 """Use this function at the end of test_main() whenever sub-processes
598 are started. This will help ensure that no extra children (zombies)
599 stick around to hog resources and create problems when looking
600 for refleaks.
601 """
602
603 # Reap all our dead child processes so we don't leave zombies around.
604 # These hog resources and might be causing some of the buildbots to die.
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000605 if hasattr(os, 'waitpid'):
606 any_process = -1
607 while True:
608 try:
609 # This will raise an exception on Windows. That's ok.
610 pid, status = os.waitpid(any_process, os.WNOHANG)
611 if pid == 0:
612 break
613 except:
614 break