blob: 17307c8d447ae1f7aa62cf4785e8dc06761a80f3 [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:
Skip Montanaro7a98be22007-08-16 14:35:24 +000073 unlink(os.path.join(dirname, modname + '.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.
Skip Montanaro7a98be22007-08-16 14:35:24 +000077 unlink(os.path.join(dirname, modname + '.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
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000103 # Find some random ports that hopefully no one is listening on.
104 # Ideally each test would clean up after itself and not continue listening
105 # on any ports. However, this isn't the case. The last port (0) is
106 # a stop-gap that asks the O/S to assign a port. Whenever the warning
107 # message below is printed, the test that is listening on the port should
108 # be fixed to close the socket at the end of the test.
109 # Another reason why we can't use a port is another process (possibly
110 # another instance of the test suite) is using the same port.
111 for port in [preferred_port, 9907, 10243, 32999, 0]:
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000112 try:
113 sock.bind((host, port))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000114 if port == 0:
115 port = sock.getsockname()[1]
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000116 return port
Guido van Rossumb940e112007-01-10 16:19:56 +0000117 except socket.error as e:
Guido van Rossume2c8f2d2007-05-09 23:43:17 +0000118 (err, msg) = e.args
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000119 if err != errno.EADDRINUSE:
120 raise
Georg Brandldb028442008-02-05 20:48:58 +0000121 print(' WARNING: failed to listen on port %d, trying another' %
122 (port, file=sys.__stderr__))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000123 raise TestFailed('unable to find port to listen on')
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000124
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000125FUZZ = 1e-6
126
127def fcmp(x, y): # fuzzy comparison function
Neal Norwitz79212992006-08-21 16:27:31 +0000128 if isinstance(x, float) or isinstance(y, float):
Fred Drake004d5e62000-10-23 17:22:08 +0000129 try:
Fred Drake004d5e62000-10-23 17:22:08 +0000130 fuzz = (abs(x) + abs(y)) * FUZZ
131 if abs(x-y) <= fuzz:
132 return 0
133 except:
134 pass
Neal Norwitz79212992006-08-21 16:27:31 +0000135 elif type(x) == type(y) and isinstance(x, (tuple, list)):
Fred Drake004d5e62000-10-23 17:22:08 +0000136 for i in range(min(len(x), len(y))):
137 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +0000138 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +0000139 return outcome
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000140 return (len(x) > len(y)) - (len(x) < len(y))
141 return (x > y) - (x < y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000142
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000143try:
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000144 str
Neal Norwitz79212992006-08-21 16:27:31 +0000145 have_unicode = True
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000146except NameError:
Neal Norwitz79212992006-08-21 16:27:31 +0000147 have_unicode = False
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000148
Finn Bock57bc5fa2002-11-01 18:02:03 +0000149is_jython = sys.platform.startswith('java')
150
Barry Warsaw559f6682001-03-23 18:04:02 +0000151# Filename used for testing
152if os.name == 'java':
153 # Jython disallows @ in module names
154 TESTFN = '$test'
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000155else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000156 TESTFN = '@test'
Walter Dörwald9b775532007-06-08 14:30:53 +0000157
158 # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
159 # TESTFN_UNICODE is a filename that can be encoded using the
160 # file system encoding, but *not* with the default (ascii) encoding
161 TESTFN_UNICODE = "@test-\xe0\xf2"
162 TESTFN_ENCODING = sys.getfilesystemencoding()
163 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
164 # able to be encoded by *either* the default or filesystem encoding.
165 # This test really only makes sense on Windows NT platforms
166 # which have special Unicode support in posixmodule.
167 if (not hasattr(sys, "getwindowsversion") or
168 sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
169 TESTFN_UNICODE_UNENCODEABLE = None
170 else:
171 # Japanese characters (I think - from bug 846133)
172 TESTFN_UNICODE_UNENCODEABLE = "@test-\u5171\u6709\u3055\u308c\u308b"
173 try:
174 # XXX - Note - should be using TESTFN_ENCODING here - but for
175 # Windows, "mbcs" currently always operates as if in
176 # errors=ignore' mode - hence we get '?' characters rather than
177 # the exception. 'Latin1' operates as we expect - ie, fails.
178 # See [ 850997 ] mbcs encoding ignores errors
179 TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
180 except UnicodeEncodeError:
181 pass
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000182 else:
Georg Brandldb028442008-02-05 20:48:58 +0000183 print('WARNING: The filename %r CAN be encoded by the filesystem. '
184 'Unicode filename tests may not be effective'
185 % TESTFN_UNICODE_UNENCODEABLE)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000186
187# Make sure we can write to TESTFN, try in /tmp if we can't
188fp = None
189try:
190 fp = open(TESTFN, 'w+')
191except IOError:
192 TMP_TESTFN = os.path.join('/tmp', TESTFN)
193 try:
194 fp = open(TMP_TESTFN, 'w+')
195 TESTFN = TMP_TESTFN
196 del TMP_TESTFN
197 except IOError:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000198 print(('WARNING: tests will fail, unable to write to: %s or %s' %
199 (TESTFN, TMP_TESTFN)))
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000200if fp is not None:
201 fp.close()
Neal Norwitz0e17f8c2006-01-23 07:51:27 +0000202 unlink(TESTFN)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000203del fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000204
Guido van Rossume26132c1998-04-23 20:13:30 +0000205def findfile(file, here=__file__):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000206 """Try to find a file on sys.path and the working directory. If it is not
207 found the argument passed to the function is returned (this does not
208 necessarily signal failure; could still be the legitimate path)."""
Fred Drake004d5e62000-10-23 17:22:08 +0000209 if os.path.isabs(file):
210 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000211 path = sys.path
212 path = [os.path.dirname(here)] + path
213 for dn in path:
214 fn = os.path.join(dn, file)
215 if os.path.exists(fn): return fn
216 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000217
218def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000219 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000220
Skip Montanaroc955f892001-01-20 19:12:54 +0000221 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000222 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000223 """
Tim Peters983874d2001-01-19 05:59:21 +0000224
Tim Petersd2bf3b72001-01-18 02:22:22 +0000225 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000226 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000227
Tim Petersc2fe6182001-10-30 23:20:46 +0000228def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000229 """Raise TestFailed if a == b is false.
230
231 This is better than verify(a == b) because, in case of failure, the
232 error message incorporates repr(a) and repr(b) so you can see the
233 inputs.
234
235 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
236 former is tested.
237 """
238
Tim Petersc2fe6182001-10-30 23:20:46 +0000239 if not (a == b):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000240 raise TestFailed("%r == %r" % (a, b))
Tim Petersc2fe6182001-10-30 23:20:46 +0000241
Tim Peters2f228e72001-05-13 00:19:31 +0000242def sortdict(dict):
243 "Like repr(dict), but in sorted order."
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000244 items = sorted(dict.items())
Tim Peters2f228e72001-05-13 00:19:31 +0000245 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
Martin v. Löwis234a34a2007-08-30 20:58:02 +0000257def open_urlresource(url, *args, **kw):
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000258 import urllib, urlparse
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000259
Guido van Rossum360e4b82007-05-14 22:51:27 +0000260 requires('urlfetch')
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):
Martin v. Löwis234a34a2007-08-30 20:58:02 +0000266 return open(fn, *args, **kw)
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000267
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)
Martin v. Löwis234a34a2007-08-30 20:58:02 +0000270 return open(fn, *args, **kw)
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000271
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000272
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
Guido van Rossumaf554a02007-08-16 23:48:43 +0000295 with catch_warning() as w:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000296 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
Thomas Woutersed03b412007-08-28 21:37:11 +0000375@contextlib.contextmanager
376def captured_stdout():
377 """Run the with statement body using a StringIO object as sys.stdout.
378 Example use::
379
380 with captured_stdout() as s:
381 print "hello"
382 assert s.getvalue() == "hello"
383 """
384 import io
385 orig_stdout = sys.stdout
386 sys.stdout = io.StringIO()
387 yield sys.stdout
388 sys.stdout = orig_stdout
389
390
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000391#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000392# Decorator for running a function in a different locale, correctly resetting
393# it afterwards.
394
395def run_with_locale(catstr, *locales):
396 def decorator(func):
397 def inner(*args, **kwds):
398 try:
399 import locale
400 category = getattr(locale, catstr)
401 orig_locale = locale.setlocale(category)
402 except AttributeError:
403 # if the test author gives us an invalid category string
404 raise
405 except:
406 # cannot retrieve original locale, so do nothing
407 locale = orig_locale = None
408 else:
409 for loc in locales:
410 try:
411 locale.setlocale(category, loc)
412 break
413 except:
414 pass
415
416 # now run the function, resetting the locale on exceptions
417 try:
418 return func(*args, **kwds)
419 finally:
420 if locale and orig_locale:
421 locale.setlocale(category, orig_locale)
Neal Norwitz221085d2007-02-25 20:55:47 +0000422 inner.__name__ = func.__name__
Thomas Wouters477c8d52006-05-27 19:21:47 +0000423 inner.__doc__ = func.__doc__
424 return inner
425 return decorator
426
427#=======================================================================
Georg Brandldb028442008-02-05 20:48:58 +0000428# Big-memory-test support. Separate from 'resources' because memory use
429# should be configurable.
Thomas Wouters477c8d52006-05-27 19:21:47 +0000430
431# Some handy shorthands. Note that these are used for byte-limits as well
432# as size-limits, in the various bigmem tests
433_1M = 1024*1024
434_1G = 1024 * _1M
435_2G = 2 * _1G
436
Thomas Woutersd2cf20e2007-08-30 22:57:53 +0000437MAX_Py_ssize_t = sys.maxsize
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000438
Thomas Wouters477c8d52006-05-27 19:21:47 +0000439def set_memlimit(limit):
440 import re
441 global max_memuse
442 sizes = {
443 'k': 1024,
444 'm': _1M,
445 'g': _1G,
446 't': 1024*_1G,
447 }
448 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
449 re.IGNORECASE | re.VERBOSE)
450 if m is None:
451 raise ValueError('Invalid memory limit %r' % (limit,))
452 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000453 if memlimit > MAX_Py_ssize_t:
454 memlimit = MAX_Py_ssize_t
455 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000456 raise ValueError('Memory limit %r too low to be useful' % (limit,))
457 max_memuse = memlimit
458
459def bigmemtest(minsize, memuse, overhead=5*_1M):
460 """Decorator for bigmem tests.
461
462 'minsize' is the minimum useful size for the test (in arbitrary,
463 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
464 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
465 independant of the testsize, and defaults to 5Mb.
466
467 The decorator tries to guess a good value for 'size' and passes it to
468 the decorated test function. If minsize * memuse is more than the
469 allowed memory use (as defined by max_memuse), the test is skipped.
470 Otherwise, minsize is adjusted upward to use up to max_memuse.
471 """
472 def decorator(f):
473 def wrapper(self):
474 if not max_memuse:
475 # If max_memuse is 0 (the default),
476 # we still want to run the tests with size set to a few kb,
477 # to make sure they work. We still want to avoid using
478 # too much memory, though, but we do that noisily.
479 maxsize = 5147
480 self.failIf(maxsize * memuse + overhead > 20 * _1M)
481 else:
482 maxsize = int((max_memuse - overhead) / memuse)
483 if maxsize < minsize:
484 # Really ought to print 'test skipped' or something
485 if verbose:
486 sys.stderr.write("Skipping %s because of memory "
487 "constraint\n" % (f.__name__,))
488 return
489 # Try to keep some breathing room in memory use
490 maxsize = max(maxsize - 50 * _1M, minsize)
491 return f(self, maxsize)
492 wrapper.minsize = minsize
493 wrapper.memuse = memuse
494 wrapper.overhead = overhead
495 return wrapper
496 return decorator
497
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000498def bigaddrspacetest(f):
499 """Decorator for tests that fill the address space."""
500 def wrapper(self):
501 if max_memuse < MAX_Py_ssize_t:
502 if verbose:
503 sys.stderr.write("Skipping %s because of memory "
504 "constraint\n" % (f.__name__,))
505 else:
506 return f(self)
507 return wrapper
508
Thomas Wouters477c8d52006-05-27 19:21:47 +0000509#=======================================================================
Guido van Rossumd8faa362007-04-27 19:54:29 +0000510# unittest integration.
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000511
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000512class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000513 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000514 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000515 test(result)
516 return result
517
518
Guido van Rossumd8faa362007-04-27 19:54:29 +0000519def _run_suite(suite):
Barry Warsawc88425e2001-09-20 06:31:22 +0000520 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000521 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000522 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000523 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000524 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000525
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000526 result = runner.run(suite)
527 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000528 if len(result.errors) == 1 and not result.failures:
529 err = result.errors[0][1]
530 elif len(result.failures) == 1 and not result.errors:
531 err = result.failures[0][1]
532 else:
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000533 err = "errors occurred; run in verbose mode for details"
Tim Peters2d84f2c2001-09-08 03:37:56 +0000534 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000535
Barry Warsawc10d6902001-09-20 06:30:41 +0000536
Walter Dörwald21d3a322003-05-01 17:45:56 +0000537def run_unittest(*classes):
538 """Run tests from unittest.TestCase-derived classes."""
Guido van Rossumd8faa362007-04-27 19:54:29 +0000539 valid_types = (unittest.TestSuite, unittest.TestCase)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000540 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000541 for cls in classes:
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000542 if isinstance(cls, str):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000543 if cls in sys.modules:
544 suite.addTest(unittest.findTestCases(sys.modules[cls]))
545 else:
546 raise ValueError("str arguments must be keys in sys.modules")
547 elif isinstance(cls, valid_types):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000548 suite.addTest(cls)
549 else:
550 suite.addTest(unittest.makeSuite(cls))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000551 _run_suite(suite)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000552
Barry Warsawc10d6902001-09-20 06:30:41 +0000553
Tim Petersa0a62222001-09-09 06:12:01 +0000554#=======================================================================
555# doctest driver.
556
557def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000558 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000559
560 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000561 test_support's belief about verbosity on to doctest. Else doctest's
562 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000563 """
564
565 import doctest
566
567 if verbosity is None:
568 verbosity = verbose
569 else:
570 verbosity = None
571
Tim Peters342ca752001-09-25 19:13:20 +0000572 # Direct doctest output (normally just errors) to real stdout; doctest
573 # output shouldn't be compared by regrtest.
574 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000575 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000576 try:
577 f, t = doctest.testmod(module, verbose=verbosity)
578 if f:
579 raise TestFailed("%d of %d doctests failed" % (f, t))
580 finally:
581 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000582 if verbose:
Georg Brandldb028442008-02-05 20:48:58 +0000583 print('doctest (%s) ... %d tests with zero failures' %
584 (module.__name__, t))
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000585 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000586
587#=======================================================================
588# Threading support to prevent reporting refleaks when running regrtest.py -R
589
590def threading_setup():
591 import threading
592 return len(threading._active), len(threading._limbo)
593
594def threading_cleanup(num_active, num_limbo):
595 import threading
596 import time
597
598 _MAX_COUNT = 10
599 count = 0
600 while len(threading._active) != num_active and count < _MAX_COUNT:
601 count += 1
602 time.sleep(0.1)
603
604 count = 0
605 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
606 count += 1
607 time.sleep(0.1)
608
609def reap_children():
610 """Use this function at the end of test_main() whenever sub-processes
611 are started. This will help ensure that no extra children (zombies)
612 stick around to hog resources and create problems when looking
613 for refleaks.
614 """
615
616 # Reap all our dead child processes so we don't leave zombies around.
617 # These hog resources and might be causing some of the buildbots to die.
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000618 if hasattr(os, 'waitpid'):
619 any_process = -1
620 while True:
621 try:
622 # This will raise an exception on Windows. That's ok.
623 pid, status = os.waitpid(any_process, os.WNOHANG)
624 if pid == 0:
625 break
626 except:
627 break