blob: 92592eb4d6f3d41765e3f9df692af19adef07084 [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
Christian Heimes23daade02008-02-25 12:39:23 +000012import shutil
Thomas Wouters902d6eb2007-01-09 23:18:33 +000013import warnings
Guido van Rossumd8faa362007-04-27 19:54:29 +000014import 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
Benjamin Peterson699adb92008-05-08 22:27:58 +000040def import_module(name, deprecated=False):
41 """Import the module to be tested, raising TestSkipped if it is not
42 available."""
43 with catch_warning(record=False):
44 if deprecated:
45 warnings.filterwarnings("ignore", ".+ module", DeprecationWarning)
46 try:
47 module = __import__(name, level=0)
48 except ImportError:
49 raise TestSkipped("No module named " + name)
50 else:
51 return module
52
Barry Warsawc0fb6052001-08-20 22:29:23 +000053verbose = 1 # Flag set to 0 by regrtest.py
Thomas Wouters477c8d52006-05-27 19:21:47 +000054use_resources = None # Flag set to [] by regrtest.py
55max_memuse = 0 # Disable bigmem tests (they will still be run with
56 # small sizes, to make sure they work.)
Guido van Rossum531661c1996-12-20 02:58:22 +000057
Tim Peters8dee8092001-09-25 20:05:11 +000058# _original_stdout is meant to hold stdout at the time regrtest began.
59# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
60# The point is to have some flavor of stdout the user can actually see.
61_original_stdout = None
62def record_original_stdout(stdout):
63 global _original_stdout
64 _original_stdout = stdout
65
66def get_original_stdout():
67 return _original_stdout or sys.stdout
68
Guido van Rossum3bead091992-01-27 17:00:37 +000069def unload(name):
Fred Drake004d5e62000-10-23 17:22:08 +000070 try:
71 del sys.modules[name]
72 except KeyError:
73 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000074
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000075def unlink(filename):
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000076 try:
77 os.unlink(filename)
78 except OSError:
79 pass
80
Christian Heimes23daade02008-02-25 12:39:23 +000081def rmtree(path):
82 try:
83 shutil.rmtree(path)
84 except OSError as e:
85 # Unix returns ENOENT, Windows returns ESRCH.
86 if e.errno not in (errno.ENOENT, errno.ESRCH):
87 raise
88
Guido van Rossum3bead091992-01-27 17:00:37 +000089def forget(modname):
Brett Cannonf1cfb622003-05-04 21:15:27 +000090 '''"Forget" a module was ever imported by removing it from sys.modules and
91 deleting any .pyc and .pyo files.'''
Fred Drake004d5e62000-10-23 17:22:08 +000092 unload(modname)
Fred Drake004d5e62000-10-23 17:22:08 +000093 for dirname in sys.path:
Skip Montanaro7a98be22007-08-16 14:35:24 +000094 unlink(os.path.join(dirname, modname + '.pyc'))
Brett Cannonf1cfb622003-05-04 21:15:27 +000095 # Deleting the .pyo file cannot be within the 'try' for the .pyc since
96 # the chance exists that there is no .pyc (and thus the 'try' statement
97 # is exited) but there is a .pyo file.
Skip Montanaro7a98be22007-08-16 14:35:24 +000098 unlink(os.path.join(dirname, modname + '.pyo'))
Guido van Rossum3bead091992-01-27 17:00:37 +000099
Tim Petersb4ee4eb2002-12-04 03:26:57 +0000100def is_resource_enabled(resource):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000101 """Test whether a resource is enabled. Known resources are set by
102 regrtest.py."""
Tim Petersb4ee4eb2002-12-04 03:26:57 +0000103 return use_resources is not None and resource in use_resources
104
Barry Warsawc0fb6052001-08-20 22:29:23 +0000105def requires(resource, msg=None):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000106 """Raise ResourceDenied if the specified resource is not available.
107
108 If the caller's module is __main__ then automatically return True. The
109 possibility of False being returned occurs when regrtest.py is executing."""
Skip Montanarod839ecd2003-04-24 19:06:57 +0000110 # see if the caller's module is __main__ - if so, treat as if
111 # the resource was set
112 if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
113 return
Tim Petersb4ee4eb2002-12-04 03:26:57 +0000114 if not is_resource_enabled(resource):
Barry Warsawc0fb6052001-08-20 22:29:23 +0000115 if msg is None:
116 msg = "Use of the `%s' resource not enabled" % resource
Fred Drake9a0db072003-02-03 15:19:30 +0000117 raise ResourceDenied(msg)
Barry Warsawc0fb6052001-08-20 22:29:23 +0000118
Christian Heimes5e696852008-04-09 08:37:03 +0000119HOST = 'localhost'
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000120
Christian Heimes5e696852008-04-09 08:37:03 +0000121def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM):
122 """Returns an unused port that should be suitable for binding. This is
123 achieved by creating a temporary socket with the same family and type as
124 the 'sock' parameter (default is AF_INET, SOCK_STREAM), and binding it to
125 the specified host address (defaults to 0.0.0.0) with the port set to 0,
126 eliciting an unused ephemeral port from the OS. The temporary socket is
127 then closed and deleted, and the ephemeral port is returned.
128
129 Either this method or bind_port() should be used for any tests where a
130 server socket needs to be bound to a particular port for the duration of
131 the test. Which one to use depends on whether the calling code is creating
132 a python socket, or if an unused port needs to be provided in a constructor
133 or passed to an external program (i.e. the -accept argument to openssl's
134 s_server mode). Always prefer bind_port() over find_unused_port() where
135 possible. Hard coded ports should *NEVER* be used. As soon as a server
136 socket is bound to a hard coded port, the ability to run multiple instances
137 of the test simultaneously on the same host is compromised, which makes the
138 test a ticking time bomb in a buildbot environment. On Unix buildbots, this
139 may simply manifest as a failed test, which can be recovered from without
140 intervention in most cases, but on Windows, the entire python process can
141 completely and utterly wedge, requiring someone to log in to the buildbot
142 and manually kill the affected process.
143
144 (This is easy to reproduce on Windows, unfortunately, and can be traced to
145 the SO_REUSEADDR socket option having different semantics on Windows versus
146 Unix/Linux. On Unix, you can't have two AF_INET SOCK_STREAM sockets bind,
147 listen and then accept connections on identical host/ports. An EADDRINUSE
148 socket.error will be raised at some point (depending on the platform and
149 the order bind and listen were called on each socket).
150
151 However, on Windows, if SO_REUSEADDR is set on the sockets, no EADDRINUSE
152 will ever be raised when attempting to bind two identical host/ports. When
153 accept() is called on each socket, the second caller's process will steal
154 the port from the first caller, leaving them both in an awkwardly wedged
155 state where they'll no longer respond to any signals or graceful kills, and
156 must be forcibly killed via OpenProcess()/TerminateProcess().
157
158 The solution on Windows is to use the SO_EXCLUSIVEADDRUSE socket option
159 instead of SO_REUSEADDR, which effectively affords the same semantics as
160 SO_REUSEADDR on Unix. Given the propensity of Unix developers in the Open
161 Source world compared to Windows ones, this is a common mistake. A quick
162 look over OpenSSL's 0.9.8g source shows that they use SO_REUSEADDR when
163 openssl.exe is called with the 's_server' option, for example. See
164 http://bugs.python.org/issue2550 for more info. The following site also
165 has a very thorough description about the implications of both REUSEADDR
166 and EXCLUSIVEADDRUSE on Windows:
167 http://msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx)
168
169 XXX: although this approach is a vast improvement on previous attempts to
170 elicit unused ports, it rests heavily on the assumption that the ephemeral
171 port returned to us by the OS won't immediately be dished back out to some
172 other process when we close and delete our temporary socket but before our
173 calling code has a chance to bind the returned port. We can deal with this
174 issue if/when we come across it.
175 """
176
177 tempsock = socket.socket(family, socktype)
178 port = bind_port(tempsock)
179 tempsock.close()
180 del tempsock
181 return port
182
183def bind_port(sock, host=HOST):
184 """Bind the socket to a free port and return the port number. Relies on
185 ephemeral ports in order to ensure we are using an unbound port. This is
186 important as many tests may be running simultaneously, especially in a
187 buildbot environment. This method raises an exception if the sock.family
188 is AF_INET and sock.type is SOCK_STREAM, *and* the socket has SO_REUSEADDR
189 or SO_REUSEPORT set on it. Tests should *never* set these socket options
190 for TCP/IP sockets. The only case for setting these options is testing
191 multicasting via multiple UDP sockets.
192
193 Additionally, if the SO_EXCLUSIVEADDRUSE socket option is available (i.e.
194 on Windows), it will be set on the socket. This will prevent anyone else
195 from bind()'ing to our host/port for the duration of the test.
196 """
197
198 if sock.family == socket.AF_INET and sock.type == socket.SOCK_STREAM:
199 if hasattr(socket, 'SO_REUSEADDR'):
200 if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 1:
201 raise TestFailed("tests should never set the SO_REUSEADDR " \
202 "socket option on TCP/IP sockets!")
203 if hasattr(socket, 'SO_REUSEPORT'):
204 if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1:
205 raise TestFailed("tests should never set the SO_REUSEPORT " \
206 "socket option on TCP/IP sockets!")
207 if hasattr(socket, 'SO_EXCLUSIVEADDRUSE'):
208 sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1)
209
210 sock.bind((host, 0))
211 port = sock.getsockname()[1]
212 return port
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000213
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000214FUZZ = 1e-6
215
216def fcmp(x, y): # fuzzy comparison function
Neal Norwitz79212992006-08-21 16:27:31 +0000217 if isinstance(x, float) or isinstance(y, float):
Fred Drake004d5e62000-10-23 17:22:08 +0000218 try:
Fred Drake004d5e62000-10-23 17:22:08 +0000219 fuzz = (abs(x) + abs(y)) * FUZZ
220 if abs(x-y) <= fuzz:
221 return 0
222 except:
223 pass
Neal Norwitz79212992006-08-21 16:27:31 +0000224 elif type(x) == type(y) and isinstance(x, (tuple, list)):
Fred Drake004d5e62000-10-23 17:22:08 +0000225 for i in range(min(len(x), len(y))):
226 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +0000227 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +0000228 return outcome
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000229 return (len(x) > len(y)) - (len(x) < len(y))
230 return (x > y) - (x < y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000231
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000232try:
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000233 str
Neal Norwitz79212992006-08-21 16:27:31 +0000234 have_unicode = True
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000235except NameError:
Neal Norwitz79212992006-08-21 16:27:31 +0000236 have_unicode = False
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000237
Finn Bock57bc5fa2002-11-01 18:02:03 +0000238is_jython = sys.platform.startswith('java')
239
Barry Warsaw559f6682001-03-23 18:04:02 +0000240# Filename used for testing
241if os.name == 'java':
242 # Jython disallows @ in module names
243 TESTFN = '$test'
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000244else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000245 TESTFN = '@test'
Walter Dörwald9b775532007-06-08 14:30:53 +0000246
247 # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
248 # TESTFN_UNICODE is a filename that can be encoded using the
249 # file system encoding, but *not* with the default (ascii) encoding
250 TESTFN_UNICODE = "@test-\xe0\xf2"
251 TESTFN_ENCODING = sys.getfilesystemencoding()
252 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
253 # able to be encoded by *either* the default or filesystem encoding.
254 # This test really only makes sense on Windows NT platforms
255 # which have special Unicode support in posixmodule.
256 if (not hasattr(sys, "getwindowsversion") or
257 sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
258 TESTFN_UNICODE_UNENCODEABLE = None
259 else:
260 # Japanese characters (I think - from bug 846133)
261 TESTFN_UNICODE_UNENCODEABLE = "@test-\u5171\u6709\u3055\u308c\u308b"
262 try:
263 # XXX - Note - should be using TESTFN_ENCODING here - but for
264 # Windows, "mbcs" currently always operates as if in
265 # errors=ignore' mode - hence we get '?' characters rather than
266 # the exception. 'Latin1' operates as we expect - ie, fails.
267 # See [ 850997 ] mbcs encoding ignores errors
268 TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
269 except UnicodeEncodeError:
270 pass
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000271 else:
Georg Brandldb028442008-02-05 20:48:58 +0000272 print('WARNING: The filename %r CAN be encoded by the filesystem. '
273 'Unicode filename tests may not be effective'
274 % TESTFN_UNICODE_UNENCODEABLE)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000275
276# Make sure we can write to TESTFN, try in /tmp if we can't
277fp = None
278try:
279 fp = open(TESTFN, 'w+')
280except IOError:
281 TMP_TESTFN = os.path.join('/tmp', TESTFN)
282 try:
283 fp = open(TMP_TESTFN, 'w+')
284 TESTFN = TMP_TESTFN
285 del TMP_TESTFN
286 except IOError:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000287 print(('WARNING: tests will fail, unable to write to: %s or %s' %
288 (TESTFN, TMP_TESTFN)))
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000289if fp is not None:
290 fp.close()
Neal Norwitz0e17f8c2006-01-23 07:51:27 +0000291 unlink(TESTFN)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000292del fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000293
Guido van Rossume26132c1998-04-23 20:13:30 +0000294def findfile(file, here=__file__):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000295 """Try to find a file on sys.path and the working directory. If it is not
296 found the argument passed to the function is returned (this does not
297 necessarily signal failure; could still be the legitimate path)."""
Fred Drake004d5e62000-10-23 17:22:08 +0000298 if os.path.isabs(file):
299 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000300 path = sys.path
301 path = [os.path.dirname(here)] + path
302 for dn in path:
303 fn = os.path.join(dn, file)
304 if os.path.exists(fn): return fn
305 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000306
307def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000308 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000309
Skip Montanaroc955f892001-01-20 19:12:54 +0000310 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000311 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000312 """
Tim Peters983874d2001-01-19 05:59:21 +0000313
Tim Petersd2bf3b72001-01-18 02:22:22 +0000314 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000315 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000316
Tim Petersc2fe6182001-10-30 23:20:46 +0000317def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000318 """Raise TestFailed if a == b is false.
319
320 This is better than verify(a == b) because, in case of failure, the
321 error message incorporates repr(a) and repr(b) so you can see the
322 inputs.
323
324 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
325 former is tested.
326 """
327
Tim Petersc2fe6182001-10-30 23:20:46 +0000328 if not (a == b):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000329 raise TestFailed("%r == %r" % (a, b))
Tim Petersc2fe6182001-10-30 23:20:46 +0000330
Tim Peters2f228e72001-05-13 00:19:31 +0000331def sortdict(dict):
332 "Like repr(dict), but in sorted order."
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000333 items = sorted(dict.items())
Tim Peters2f228e72001-05-13 00:19:31 +0000334 reprpairs = ["%r: %r" % pair for pair in items]
335 withcommas = ", ".join(reprpairs)
336 return "{%s}" % withcommas
337
Thomas Wouters89f507f2006-12-13 04:49:30 +0000338def check_syntax_error(testcase, statement):
Jeremy Hylton47793992001-02-19 15:35:26 +0000339 try:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000340 compile(statement, '<test string>', 'exec')
Jeremy Hylton47793992001-02-19 15:35:26 +0000341 except SyntaxError:
342 pass
343 else:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000344 testcase.fail('Missing SyntaxError: "%s"' % statement)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000345
Martin v. Löwis234a34a2007-08-30 20:58:02 +0000346def open_urlresource(url, *args, **kw):
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000347 import urllib, urlparse
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000348
Guido van Rossum360e4b82007-05-14 22:51:27 +0000349 requires('urlfetch')
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000350 filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL!
351
352 for path in [os.path.curdir, os.path.pardir]:
353 fn = os.path.join(path, filename)
354 if os.path.exists(fn):
Martin v. Löwis234a34a2007-08-30 20:58:02 +0000355 return open(fn, *args, **kw)
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000356
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000357 print('\tfetching %s ...' % url, file=get_original_stdout())
Hye-Shik Changaaa2f1d2005-12-10 17:44:27 +0000358 fn, _ = urllib.urlretrieve(url, filename)
Martin v. Löwis234a34a2007-08-30 20:58:02 +0000359 return open(fn, *args, **kw)
Thomas Wouters9fe394c2007-02-05 01:24:16 +0000360
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000361
Guido van Rossumd8faa362007-04-27 19:54:29 +0000362class WarningMessage(object):
363 "Holds the result of the latest showwarning() call"
364 def __init__(self):
365 self.message = None
366 self.category = None
367 self.filename = None
368 self.lineno = None
369
Christian Heimes33fe8092008-04-13 13:53:33 +0000370 def _showwarning(self, message, category, filename, lineno, file=None,
371 line=None):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000372 self.message = message
373 self.category = category
374 self.filename = filename
375 self.lineno = lineno
Christian Heimes33fe8092008-04-13 13:53:33 +0000376 self.line = line
377
378 def reset(self):
379 self._showwarning(*((None,)*6))
380
381 def __str__(self):
382 return ("{message : %r, category : %r, filename : %r, lineno : %s, "
383 "line : %r}" % (self.message,
384 self.category.__name__ if self.category else None,
385 self.filename, self.lineno, self.line))
386
Guido van Rossumd8faa362007-04-27 19:54:29 +0000387
388@contextlib.contextmanager
Benjamin Peterson699adb92008-05-08 22:27:58 +0000389def catch_warning(module=warnings, record=True):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000390 """
391 Guard the warnings filter from being permanently changed and record the
392 data of the last warning that has been issued.
393
394 Use like this:
395
Guido van Rossumaf554a02007-08-16 23:48:43 +0000396 with catch_warning() as w:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000397 warnings.warn("foo")
398 assert str(w.message) == "foo"
399 """
Christian Heimes33fe8092008-04-13 13:53:33 +0000400 original_filters = module.filters[:]
401 original_showwarning = module.showwarning
Benjamin Peterson699adb92008-05-08 22:27:58 +0000402 if record:
403 warning_obj = WarningMessage()
404 module.showwarning = warning_obj._showwarning
Guido van Rossumd8faa362007-04-27 19:54:29 +0000405 try:
Benjamin Peterson699adb92008-05-08 22:27:58 +0000406 yield warning_obj if record else None
Guido van Rossumd8faa362007-04-27 19:54:29 +0000407 finally:
Christian Heimes33fe8092008-04-13 13:53:33 +0000408 module.showwarning = original_showwarning
409 module.filters = original_filters
Guido van Rossumd8faa362007-04-27 19:54:29 +0000410
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000411class EnvironmentVarGuard(object):
412
413 """Class to help protect the environment variable properly. Can be used as
414 a context manager."""
415
416 def __init__(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000417 self._environ = os.environ
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000418 self._unset = set()
419 self._reset = dict()
420
421 def set(self, envvar, value):
422 if envvar not in self._environ:
423 self._unset.add(envvar)
424 else:
425 self._reset[envvar] = self._environ[envvar]
426 self._environ[envvar] = value
427
428 def unset(self, envvar):
429 if envvar in self._environ:
430 self._reset[envvar] = self._environ[envvar]
431 del self._environ[envvar]
432
433 def __enter__(self):
434 return self
435
436 def __exit__(self, *ignore_exc):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000437 for envvar, value in self._reset.items():
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000438 self._environ[envvar] = value
439 for unset in self._unset:
440 del self._environ[unset]
441
Guido van Rossumd8faa362007-04-27 19:54:29 +0000442class TransientResource(object):
443
444 """Raise ResourceDenied if an exception is raised while the context manager
445 is in effect that matches the specified exception and attributes."""
446
447 def __init__(self, exc, **kwargs):
448 self.exc = exc
449 self.attrs = kwargs
450
451 def __enter__(self):
452 return self
453
454 def __exit__(self, type_=None, value=None, traceback=None):
455 """If type_ is a subclass of self.exc and value has attributes matching
456 self.attrs, raise ResourceDenied. Otherwise let the exception
457 propagate (if any)."""
458 if type_ is not None and issubclass(self.exc, type_):
459 for attr, attr_value in self.attrs.items():
460 if not hasattr(value, attr):
461 break
462 if getattr(value, attr) != attr_value:
463 break
464 else:
465 raise ResourceDenied("an optional resource is not available")
466
467
468def transient_internet():
469 """Return a context manager that raises ResourceDenied when various issues
470 with the Internet connection manifest themselves as exceptions."""
471 time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
472 socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
473 ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
474 return contextlib.nested(time_out, socket_peer_reset, ioerror_peer_reset)
475
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000476
Thomas Woutersed03b412007-08-28 21:37:11 +0000477@contextlib.contextmanager
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000478def captured_output(stream_name):
479 """Run the 'with' statement body using a StringIO object in place of a
480 specific attribute on the sys module.
481 Example use (with 'stream_name=stdout')::
Thomas Woutersed03b412007-08-28 21:37:11 +0000482
483 with captured_stdout() as s:
484 print "hello"
485 assert s.getvalue() == "hello"
486 """
487 import io
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000488 orig_stdout = getattr(sys, stream_name)
489 setattr(sys, stream_name, io.StringIO())
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000490 try:
491 yield getattr(sys, stream_name)
492 finally:
493 setattr(sys, stream_name, orig_stdout)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000494
495def captured_stdout():
496 return captured_output("stdout")
Thomas Woutersed03b412007-08-28 21:37:11 +0000497
498
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000499#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000500# Decorator for running a function in a different locale, correctly resetting
501# it afterwards.
502
503def run_with_locale(catstr, *locales):
504 def decorator(func):
505 def inner(*args, **kwds):
506 try:
507 import locale
508 category = getattr(locale, catstr)
509 orig_locale = locale.setlocale(category)
510 except AttributeError:
511 # if the test author gives us an invalid category string
512 raise
513 except:
514 # cannot retrieve original locale, so do nothing
515 locale = orig_locale = None
516 else:
517 for loc in locales:
518 try:
519 locale.setlocale(category, loc)
520 break
521 except:
522 pass
523
524 # now run the function, resetting the locale on exceptions
525 try:
526 return func(*args, **kwds)
527 finally:
528 if locale and orig_locale:
529 locale.setlocale(category, orig_locale)
Neal Norwitz221085d2007-02-25 20:55:47 +0000530 inner.__name__ = func.__name__
Thomas Wouters477c8d52006-05-27 19:21:47 +0000531 inner.__doc__ = func.__doc__
532 return inner
533 return decorator
534
535#=======================================================================
Georg Brandldb028442008-02-05 20:48:58 +0000536# Big-memory-test support. Separate from 'resources' because memory use
537# should be configurable.
Thomas Wouters477c8d52006-05-27 19:21:47 +0000538
539# Some handy shorthands. Note that these are used for byte-limits as well
540# as size-limits, in the various bigmem tests
541_1M = 1024*1024
542_1G = 1024 * _1M
543_2G = 2 * _1G
544
Thomas Woutersd2cf20e2007-08-30 22:57:53 +0000545MAX_Py_ssize_t = sys.maxsize
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000546
Thomas Wouters477c8d52006-05-27 19:21:47 +0000547def set_memlimit(limit):
548 import re
549 global max_memuse
550 sizes = {
551 'k': 1024,
552 'm': _1M,
553 'g': _1G,
554 't': 1024*_1G,
555 }
556 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
557 re.IGNORECASE | re.VERBOSE)
558 if m is None:
559 raise ValueError('Invalid memory limit %r' % (limit,))
560 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000561 if memlimit > MAX_Py_ssize_t:
562 memlimit = MAX_Py_ssize_t
563 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000564 raise ValueError('Memory limit %r too low to be useful' % (limit,))
565 max_memuse = memlimit
566
567def bigmemtest(minsize, memuse, overhead=5*_1M):
568 """Decorator for bigmem tests.
569
570 'minsize' is the minimum useful size for the test (in arbitrary,
571 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
572 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
Christian Heimes33fe8092008-04-13 13:53:33 +0000573 independent of the testsize, and defaults to 5Mb.
Thomas Wouters477c8d52006-05-27 19:21:47 +0000574
575 The decorator tries to guess a good value for 'size' and passes it to
576 the decorated test function. If minsize * memuse is more than the
577 allowed memory use (as defined by max_memuse), the test is skipped.
578 Otherwise, minsize is adjusted upward to use up to max_memuse.
579 """
580 def decorator(f):
581 def wrapper(self):
582 if not max_memuse:
583 # If max_memuse is 0 (the default),
584 # we still want to run the tests with size set to a few kb,
585 # to make sure they work. We still want to avoid using
586 # too much memory, though, but we do that noisily.
587 maxsize = 5147
588 self.failIf(maxsize * memuse + overhead > 20 * _1M)
589 else:
590 maxsize = int((max_memuse - overhead) / memuse)
591 if maxsize < minsize:
592 # Really ought to print 'test skipped' or something
593 if verbose:
594 sys.stderr.write("Skipping %s because of memory "
595 "constraint\n" % (f.__name__,))
596 return
597 # Try to keep some breathing room in memory use
598 maxsize = max(maxsize - 50 * _1M, minsize)
599 return f(self, maxsize)
600 wrapper.minsize = minsize
601 wrapper.memuse = memuse
602 wrapper.overhead = overhead
603 return wrapper
604 return decorator
605
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000606def bigaddrspacetest(f):
607 """Decorator for tests that fill the address space."""
608 def wrapper(self):
609 if max_memuse < MAX_Py_ssize_t:
610 if verbose:
611 sys.stderr.write("Skipping %s because of memory "
612 "constraint\n" % (f.__name__,))
613 else:
614 return f(self)
615 return wrapper
616
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617#=======================================================================
Guido van Rossumd8faa362007-04-27 19:54:29 +0000618# unittest integration.
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000619
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000620class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000621 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000622 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000623 test(result)
624 return result
625
626
Guido van Rossumd8faa362007-04-27 19:54:29 +0000627def _run_suite(suite):
Barry Warsawc88425e2001-09-20 06:31:22 +0000628 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000629 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000630 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000631 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000632 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000633
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000634 result = runner.run(suite)
635 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000636 if len(result.errors) == 1 and not result.failures:
637 err = result.errors[0][1]
638 elif len(result.failures) == 1 and not result.errors:
639 err = result.failures[0][1]
640 else:
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000641 err = "errors occurred; run in verbose mode for details"
Tim Peters2d84f2c2001-09-08 03:37:56 +0000642 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000643
Barry Warsawc10d6902001-09-20 06:30:41 +0000644
Walter Dörwald21d3a322003-05-01 17:45:56 +0000645def run_unittest(*classes):
646 """Run tests from unittest.TestCase-derived classes."""
Guido van Rossumd8faa362007-04-27 19:54:29 +0000647 valid_types = (unittest.TestSuite, unittest.TestCase)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000648 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000649 for cls in classes:
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000650 if isinstance(cls, str):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000651 if cls in sys.modules:
652 suite.addTest(unittest.findTestCases(sys.modules[cls]))
653 else:
654 raise ValueError("str arguments must be keys in sys.modules")
655 elif isinstance(cls, valid_types):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000656 suite.addTest(cls)
657 else:
658 suite.addTest(unittest.makeSuite(cls))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000659 _run_suite(suite)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000660
Barry Warsawc10d6902001-09-20 06:30:41 +0000661
Tim Petersa0a62222001-09-09 06:12:01 +0000662#=======================================================================
663# doctest driver.
664
665def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000666 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000667
668 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000669 test_support's belief about verbosity on to doctest. Else doctest's
670 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000671 """
672
673 import doctest
674
675 if verbosity is None:
676 verbosity = verbose
677 else:
678 verbosity = None
679
Tim Peters342ca752001-09-25 19:13:20 +0000680 # Direct doctest output (normally just errors) to real stdout; doctest
681 # output shouldn't be compared by regrtest.
682 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000683 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000684 try:
685 f, t = doctest.testmod(module, verbose=verbosity)
686 if f:
687 raise TestFailed("%d of %d doctests failed" % (f, t))
688 finally:
689 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000690 if verbose:
Georg Brandldb028442008-02-05 20:48:58 +0000691 print('doctest (%s) ... %d tests with zero failures' %
692 (module.__name__, t))
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000693 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000694
695#=======================================================================
696# Threading support to prevent reporting refleaks when running regrtest.py -R
697
698def threading_setup():
699 import threading
700 return len(threading._active), len(threading._limbo)
701
702def threading_cleanup(num_active, num_limbo):
703 import threading
704 import time
705
706 _MAX_COUNT = 10
707 count = 0
708 while len(threading._active) != num_active and count < _MAX_COUNT:
709 count += 1
710 time.sleep(0.1)
711
712 count = 0
713 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
714 count += 1
715 time.sleep(0.1)
716
717def reap_children():
718 """Use this function at the end of test_main() whenever sub-processes
719 are started. This will help ensure that no extra children (zombies)
720 stick around to hog resources and create problems when looking
721 for refleaks.
722 """
723
724 # Reap all our dead child processes so we don't leave zombies around.
725 # These hog resources and might be causing some of the buildbots to die.
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000726 if hasattr(os, 'waitpid'):
727 any_process = -1
728 while True:
729 try:
730 # This will raise an exception on Windows. That's ok.
731 pid, status = os.waitpid(any_process, os.WNOHANG)
732 if pid == 0:
733 break
734 except:
735 break