blob: 2829c5566d33403bf6db95e5cc7e10ae8b6e81ec [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
Fred Drakecd1b1dd2001-03-21 18:26:33 +00006import sys
7
Fred Drake1790dd42000-07-24 06:55:00 +00008class Error(Exception):
Fred Drake004d5e62000-10-23 17:22:08 +00009 """Base class for regression test exceptions."""
Fred Drake1790dd42000-07-24 06:55:00 +000010
11class TestFailed(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000012 """Test failed."""
Fred Drake1790dd42000-07-24 06:55:00 +000013
14class TestSkipped(Error):
Fred Drake004d5e62000-10-23 17:22:08 +000015 """Test skipped.
Fred Drake1790dd42000-07-24 06:55:00 +000016
Fred Drake004d5e62000-10-23 17:22:08 +000017 This can be raised to indicate that a test was deliberatly
18 skipped, but not because a feature wasn't available. For
19 example, if some resource can't be used, such as the network
20 appears to be unavailable, this should be raised instead of
21 TestFailed.
Fred Drake004d5e62000-10-23 17:22:08 +000022 """
Fred Drake1790dd42000-07-24 06:55:00 +000023
Fred Drake9a0db072003-02-03 15:19:30 +000024class ResourceDenied(TestSkipped):
25 """Test skipped because it requested a disallowed resource.
26
27 This is raised when a test calls requires() for a resource that
28 has not be enabled. It is used to distinguish between expected
29 and unexpected skips.
30 """
31
Barry Warsawc0fb6052001-08-20 22:29:23 +000032verbose = 1 # Flag set to 0 by regrtest.py
Thomas Wouters477c8d52006-05-27 19:21:47 +000033use_resources = None # Flag set to [] by regrtest.py
34max_memuse = 0 # Disable bigmem tests (they will still be run with
35 # small sizes, to make sure they work.)
Guido van Rossum531661c1996-12-20 02:58:22 +000036
Tim Peters8dee8092001-09-25 20:05:11 +000037# _original_stdout is meant to hold stdout at the time regrtest began.
38# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
39# The point is to have some flavor of stdout the user can actually see.
40_original_stdout = None
41def record_original_stdout(stdout):
42 global _original_stdout
43 _original_stdout = stdout
44
45def get_original_stdout():
46 return _original_stdout or sys.stdout
47
Guido van Rossum3bead091992-01-27 17:00:37 +000048def unload(name):
Fred Drake004d5e62000-10-23 17:22:08 +000049 try:
50 del sys.modules[name]
51 except KeyError:
52 pass
Guido van Rossum3bead091992-01-27 17:00:37 +000053
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000054def unlink(filename):
55 import os
56 try:
57 os.unlink(filename)
58 except OSError:
59 pass
60
Guido van Rossum3bead091992-01-27 17:00:37 +000061def forget(modname):
Brett Cannonf1cfb622003-05-04 21:15:27 +000062 '''"Forget" a module was ever imported by removing it from sys.modules and
63 deleting any .pyc and .pyo files.'''
Fred Drake004d5e62000-10-23 17:22:08 +000064 unload(modname)
Fred Drakecd1b1dd2001-03-21 18:26:33 +000065 import os
Fred Drake004d5e62000-10-23 17:22:08 +000066 for dirname in sys.path:
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000067 unlink(os.path.join(dirname, modname + os.extsep + 'pyc'))
Brett Cannonf1cfb622003-05-04 21:15:27 +000068 # Deleting the .pyo file cannot be within the 'try' for the .pyc since
69 # the chance exists that there is no .pyc (and thus the 'try' statement
70 # is exited) but there is a .pyo file.
Neal Norwitz0e17f8c2006-01-23 07:51:27 +000071 unlink(os.path.join(dirname, modname + os.extsep + 'pyo'))
Guido van Rossum3bead091992-01-27 17:00:37 +000072
Tim Petersb4ee4eb2002-12-04 03:26:57 +000073def is_resource_enabled(resource):
Brett Cannonf1cfb622003-05-04 21:15:27 +000074 """Test whether a resource is enabled. Known resources are set by
75 regrtest.py."""
Tim Petersb4ee4eb2002-12-04 03:26:57 +000076 return use_resources is not None and resource in use_resources
77
Barry Warsawc0fb6052001-08-20 22:29:23 +000078def requires(resource, msg=None):
Brett Cannonf1cfb622003-05-04 21:15:27 +000079 """Raise ResourceDenied if the specified resource is not available.
80
81 If the caller's module is __main__ then automatically return True. The
82 possibility of False being returned occurs when regrtest.py is executing."""
Skip Montanarod839ecd2003-04-24 19:06:57 +000083 # see if the caller's module is __main__ - if so, treat as if
84 # the resource was set
85 if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
86 return
Tim Petersb4ee4eb2002-12-04 03:26:57 +000087 if not is_resource_enabled(resource):
Barry Warsawc0fb6052001-08-20 22:29:23 +000088 if msg is None:
89 msg = "Use of the `%s' resource not enabled" % resource
Fred Drake9a0db072003-02-03 15:19:30 +000090 raise ResourceDenied(msg)
Barry Warsawc0fb6052001-08-20 22:29:23 +000091
Thomas Wouters0e3f5912006-08-11 14:57:12 +000092def bind_port(sock, host='', preferred_port=54321):
93 """Try to bind the sock to a port. If we are running multiple
94 tests and we don't try multiple ports, the test can fails. This
95 makes the test more robust."""
96
97 import socket, errno
98 # some random ports that hopefully no one is listening on.
99 for port in [preferred_port, 9907, 10243, 32999]:
100 try:
101 sock.bind((host, port))
102 return port
103 except socket.error, (err, msg):
104 if err != errno.EADDRINUSE:
105 raise
106 print >>sys.__stderr__, \
107 ' WARNING: failed to listen on port %d, trying another' % port
108 raise TestFailed, 'unable to find port to listen on'
109
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000110FUZZ = 1e-6
111
112def fcmp(x, y): # fuzzy comparison function
Neal Norwitz79212992006-08-21 16:27:31 +0000113 if isinstance(x, float) or isinstance(y, float):
Fred Drake004d5e62000-10-23 17:22:08 +0000114 try:
Fred Drake004d5e62000-10-23 17:22:08 +0000115 fuzz = (abs(x) + abs(y)) * FUZZ
116 if abs(x-y) <= fuzz:
117 return 0
118 except:
119 pass
Neal Norwitz79212992006-08-21 16:27:31 +0000120 elif type(x) == type(y) and isinstance(x, (tuple, list)):
Fred Drake004d5e62000-10-23 17:22:08 +0000121 for i in range(min(len(x), len(y))):
122 outcome = fcmp(x[i], y[i])
Fred Drake132dce22000-12-12 23:11:42 +0000123 if outcome != 0:
Fred Drake004d5e62000-10-23 17:22:08 +0000124 return outcome
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000125 return (len(x) > len(y)) - (len(x) < len(y))
126 return (x > y) - (x < y)
Guido van Rossum35fb82a1993-01-26 13:04:43 +0000127
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000128try:
129 unicode
Neal Norwitz79212992006-08-21 16:27:31 +0000130 have_unicode = True
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000131except NameError:
Neal Norwitz79212992006-08-21 16:27:31 +0000132 have_unicode = False
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000133
Finn Bock57bc5fa2002-11-01 18:02:03 +0000134is_jython = sys.platform.startswith('java')
135
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000136import os
Barry Warsaw559f6682001-03-23 18:04:02 +0000137# Filename used for testing
138if os.name == 'java':
139 # Jython disallows @ in module names
140 TESTFN = '$test'
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000141elif os.name == 'riscos':
142 TESTFN = 'testfile'
143else:
Barry Warsaw559f6682001-03-23 18:04:02 +0000144 TESTFN = '@test'
Mark Hammondef8b6542001-05-13 08:04:26 +0000145 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000146 if have_unicode:
Mark Hammondb337dd92003-12-03 01:27:23 +0000147 # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
148 # TESTFN_UNICODE is a filename that can be encoded using the
149 # file system encoding, but *not* with the default (ascii) encoding
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000150 if isinstance('', unicode):
151 # python -U
152 # XXX perhaps unicode() should accept Unicode strings?
Tim Petersc6c5ece2003-12-04 05:39:43 +0000153 TESTFN_UNICODE = "@test-\xe0\xf2"
Martin v. Löwis2411a2d2002-11-09 19:57:26 +0000154 else:
Tim Petersc6c5ece2003-12-04 05:39:43 +0000155 # 2 latin characters.
156 TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1")
157 TESTFN_ENCODING = sys.getfilesystemencoding()
158 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
Mark Hammondb337dd92003-12-03 01:27:23 +0000159 # able to be encoded by *either* the default or filesystem encoding.
Tim Petersc6c5ece2003-12-04 05:39:43 +0000160 # This test really only makes sense on Windows NT platforms
Mark Hammond2e8624c2003-12-03 22:16:47 +0000161 # which have special Unicode support in posixmodule.
Tim Petersc6c5ece2003-12-04 05:39:43 +0000162 if (not hasattr(sys, "getwindowsversion") or
163 sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
Tim Peters58eb11c2004-01-18 20:29:55 +0000164 TESTFN_UNICODE_UNENCODEABLE = None
Mark Hammondb337dd92003-12-03 01:27:23 +0000165 else:
Mark Hammond2e8624c2003-12-03 22:16:47 +0000166 # Japanese characters (I think - from bug 846133)
Martin v. Löwise2713be2005-03-08 15:03:08 +0000167 TESTFN_UNICODE_UNENCODEABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
Mark Hammond2e8624c2003-12-03 22:16:47 +0000168 try:
169 # XXX - Note - should be using TESTFN_ENCODING here - but for
Tim Petersc6c5ece2003-12-04 05:39:43 +0000170 # Windows, "mbcs" currently always operates as if in
Mark Hammond2e8624c2003-12-03 22:16:47 +0000171 # errors=ignore' mode - hence we get '?' characters rather than
172 # the exception. 'Latin1' operates as we expect - ie, fails.
173 # See [ 850997 ] mbcs encoding ignores errors
174 TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
175 except UnicodeEncodeError:
176 pass
177 else:
178 print \
179 'WARNING: The filename %r CAN be encoded by the filesystem. ' \
180 'Unicode filename tests may not be effective' \
181 % TESTFN_UNICODE_UNENCODEABLE
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000182
183# Make sure we can write to TESTFN, try in /tmp if we can't
184fp = None
185try:
186 fp = open(TESTFN, 'w+')
187except IOError:
188 TMP_TESTFN = os.path.join('/tmp', TESTFN)
189 try:
190 fp = open(TMP_TESTFN, 'w+')
191 TESTFN = TMP_TESTFN
192 del TMP_TESTFN
193 except IOError:
Tim Peters3de75262002-11-09 05:26:15 +0000194 print ('WARNING: tests will fail, unable to write to: %s or %s' %
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000195 (TESTFN, TMP_TESTFN))
196if fp is not None:
197 fp.close()
Neal Norwitz0e17f8c2006-01-23 07:51:27 +0000198 unlink(TESTFN)
Neal Norwitz26a1eef2002-11-03 00:35:53 +0000199del os, fp
Guido van Rossuma8f7e592001-03-13 09:31:07 +0000200
Guido van Rossume26132c1998-04-23 20:13:30 +0000201def findfile(file, here=__file__):
Brett Cannonf1cfb622003-05-04 21:15:27 +0000202 """Try to find a file on sys.path and the working directory. If it is not
203 found the argument passed to the function is returned (this does not
204 necessarily signal failure; could still be the legitimate path)."""
Fred Drake004d5e62000-10-23 17:22:08 +0000205 import os
206 if os.path.isabs(file):
207 return file
Fred Drake004d5e62000-10-23 17:22:08 +0000208 path = sys.path
209 path = [os.path.dirname(here)] + path
210 for dn in path:
211 fn = os.path.join(dn, file)
212 if os.path.exists(fn): return fn
213 return file
Marc-André Lemburg36619082001-01-17 19:11:13 +0000214
215def verify(condition, reason='test failed'):
Guido van Rossuma1374e42001-01-19 19:01:56 +0000216 """Verify that condition is true. If not, raise TestFailed.
Marc-André Lemburg36619082001-01-17 19:11:13 +0000217
Skip Montanaroc955f892001-01-20 19:12:54 +0000218 The optional argument reason can be given to provide
Tim Peters983874d2001-01-19 05:59:21 +0000219 a better error text.
Tim Petersd2bf3b72001-01-18 02:22:22 +0000220 """
Tim Peters983874d2001-01-19 05:59:21 +0000221
Tim Petersd2bf3b72001-01-18 02:22:22 +0000222 if not condition:
Guido van Rossuma1374e42001-01-19 19:01:56 +0000223 raise TestFailed(reason)
Jeremy Hylton47793992001-02-19 15:35:26 +0000224
Tim Petersc2fe6182001-10-30 23:20:46 +0000225def vereq(a, b):
Tim Peters77902972001-12-29 17:34:57 +0000226 """Raise TestFailed if a == b is false.
227
228 This is better than verify(a == b) because, in case of failure, the
229 error message incorporates repr(a) and repr(b) so you can see the
230 inputs.
231
232 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
233 former is tested.
234 """
235
Tim Petersc2fe6182001-10-30 23:20:46 +0000236 if not (a == b):
237 raise TestFailed, "%r == %r" % (a, b)
238
Tim Peters2f228e72001-05-13 00:19:31 +0000239def sortdict(dict):
240 "Like repr(dict), but in sorted order."
241 items = dict.items()
242 items.sort()
243 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')
267 print >> get_original_stdout(), '\tfetching %s ...' % url
268 fn, _ = urllib.urlretrieve(url, filename)
269 return open(fn)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000270
271#=======================================================================
Thomas Wouters477c8d52006-05-27 19:21:47 +0000272# Decorator for running a function in a different locale, correctly resetting
273# it afterwards.
274
275def run_with_locale(catstr, *locales):
276 def decorator(func):
277 def inner(*args, **kwds):
278 try:
279 import locale
280 category = getattr(locale, catstr)
281 orig_locale = locale.setlocale(category)
282 except AttributeError:
283 # if the test author gives us an invalid category string
284 raise
285 except:
286 # cannot retrieve original locale, so do nothing
287 locale = orig_locale = None
288 else:
289 for loc in locales:
290 try:
291 locale.setlocale(category, loc)
292 break
293 except:
294 pass
295
296 # now run the function, resetting the locale on exceptions
297 try:
298 return func(*args, **kwds)
299 finally:
300 if locale and orig_locale:
301 locale.setlocale(category, orig_locale)
302 inner.func_name = func.func_name
303 inner.__doc__ = func.__doc__
304 return inner
305 return decorator
306
307#=======================================================================
308# Big-memory-test support. Separate from 'resources' because memory use should be configurable.
309
310# Some handy shorthands. Note that these are used for byte-limits as well
311# as size-limits, in the various bigmem tests
312_1M = 1024*1024
313_1G = 1024 * _1M
314_2G = 2 * _1G
315
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000316# Hack to get at the maximum value an internal index can take.
317class _Dummy:
318 def __getslice__(self, i, j):
319 return j
320MAX_Py_ssize_t = _Dummy()[:]
321
Thomas Wouters477c8d52006-05-27 19:21:47 +0000322def set_memlimit(limit):
323 import re
324 global max_memuse
325 sizes = {
326 'k': 1024,
327 'm': _1M,
328 'g': _1G,
329 't': 1024*_1G,
330 }
331 m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit,
332 re.IGNORECASE | re.VERBOSE)
333 if m is None:
334 raise ValueError('Invalid memory limit %r' % (limit,))
335 memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()])
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000336 if memlimit > MAX_Py_ssize_t:
337 memlimit = MAX_Py_ssize_t
338 if memlimit < _2G - 1:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000339 raise ValueError('Memory limit %r too low to be useful' % (limit,))
340 max_memuse = memlimit
341
342def bigmemtest(minsize, memuse, overhead=5*_1M):
343 """Decorator for bigmem tests.
344
345 'minsize' is the minimum useful size for the test (in arbitrary,
346 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
347 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
348 independant of the testsize, and defaults to 5Mb.
349
350 The decorator tries to guess a good value for 'size' and passes it to
351 the decorated test function. If minsize * memuse is more than the
352 allowed memory use (as defined by max_memuse), the test is skipped.
353 Otherwise, minsize is adjusted upward to use up to max_memuse.
354 """
355 def decorator(f):
356 def wrapper(self):
357 if not max_memuse:
358 # If max_memuse is 0 (the default),
359 # we still want to run the tests with size set to a few kb,
360 # to make sure they work. We still want to avoid using
361 # too much memory, though, but we do that noisily.
362 maxsize = 5147
363 self.failIf(maxsize * memuse + overhead > 20 * _1M)
364 else:
365 maxsize = int((max_memuse - overhead) / memuse)
366 if maxsize < minsize:
367 # Really ought to print 'test skipped' or something
368 if verbose:
369 sys.stderr.write("Skipping %s because of memory "
370 "constraint\n" % (f.__name__,))
371 return
372 # Try to keep some breathing room in memory use
373 maxsize = max(maxsize - 50 * _1M, minsize)
374 return f(self, maxsize)
375 wrapper.minsize = minsize
376 wrapper.memuse = memuse
377 wrapper.overhead = overhead
378 return wrapper
379 return decorator
380
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000381def bigaddrspacetest(f):
382 """Decorator for tests that fill the address space."""
383 def wrapper(self):
384 if max_memuse < MAX_Py_ssize_t:
385 if verbose:
386 sys.stderr.write("Skipping %s because of memory "
387 "constraint\n" % (f.__name__,))
388 else:
389 return f(self)
390 return wrapper
391
Thomas Wouters477c8d52006-05-27 19:21:47 +0000392#=======================================================================
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000393# Preliminary PyUNIT integration.
394
395import unittest
396
397
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000398class BasicTestRunner:
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000399 def run(self, test):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000400 result = unittest.TestResult()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000401 test(result)
402 return result
403
404
Fred Drake26641032001-10-04 19:46:07 +0000405def run_suite(suite, testclass=None):
Barry Warsawc88425e2001-09-20 06:31:22 +0000406 """Run tests from a unittest.TestSuite-derived class."""
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000407 if verbose:
Fred Drake84a59342001-03-23 04:21:17 +0000408 runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000409 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000410 runner = BasicTestRunner()
Fred Drakecd1b1dd2001-03-21 18:26:33 +0000411
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000412 result = runner.run(suite)
413 if not result.wasSuccessful():
Fred Drake14f6c182001-07-16 18:51:32 +0000414 if len(result.errors) == 1 and not result.failures:
415 err = result.errors[0][1]
416 elif len(result.failures) == 1 and not result.errors:
417 err = result.failures[0][1]
418 else:
Fred Drake26641032001-10-04 19:46:07 +0000419 if testclass is None:
420 msg = "errors occurred; run in verbose mode for details"
421 else:
422 msg = "errors occurred in %s.%s" \
423 % (testclass.__module__, testclass.__name__)
424 raise TestFailed(msg)
Tim Peters2d84f2c2001-09-08 03:37:56 +0000425 raise TestFailed(err)
Tim Petersa0a62222001-09-09 06:12:01 +0000426
Barry Warsawc10d6902001-09-20 06:30:41 +0000427
Walter Dörwald21d3a322003-05-01 17:45:56 +0000428def run_unittest(*classes):
429 """Run tests from unittest.TestCase-derived classes."""
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000430 suite = unittest.TestSuite()
Walter Dörwald21d3a322003-05-01 17:45:56 +0000431 for cls in classes:
Raymond Hettingerf3590622003-07-16 04:29:42 +0000432 if isinstance(cls, (unittest.TestSuite, unittest.TestCase)):
Raymond Hettinger21d99872003-07-16 02:59:32 +0000433 suite.addTest(cls)
434 else:
435 suite.addTest(unittest.makeSuite(cls))
Walter Dörwald21d3a322003-05-01 17:45:56 +0000436 if len(classes)==1:
437 testclass = classes[0]
438 else:
439 testclass = None
440 run_suite(suite, testclass)
Raymond Hettinger9dcbbea2003-04-27 07:54:23 +0000441
Barry Warsawc10d6902001-09-20 06:30:41 +0000442
Tim Petersa0a62222001-09-09 06:12:01 +0000443#=======================================================================
444# doctest driver.
445
446def run_doctest(module, verbosity=None):
Tim Peters17111f32001-10-03 04:08:26 +0000447 """Run doctest on the given module. Return (#failures, #tests).
Tim Petersa0a62222001-09-09 06:12:01 +0000448
449 If optional argument verbosity is not specified (or is None), pass
Tim Petersbea3fb82001-09-10 01:39:21 +0000450 test_support's belief about verbosity on to doctest. Else doctest's
451 usual behavior is used (it searches sys.argv for -v).
Tim Petersa0a62222001-09-09 06:12:01 +0000452 """
453
454 import doctest
455
456 if verbosity is None:
457 verbosity = verbose
458 else:
459 verbosity = None
460
Tim Peters342ca752001-09-25 19:13:20 +0000461 # Direct doctest output (normally just errors) to real stdout; doctest
462 # output shouldn't be compared by regrtest.
463 save_stdout = sys.stdout
Tim Peters8dee8092001-09-25 20:05:11 +0000464 sys.stdout = get_original_stdout()
Tim Peters342ca752001-09-25 19:13:20 +0000465 try:
466 f, t = doctest.testmod(module, verbose=verbosity)
467 if f:
468 raise TestFailed("%d of %d doctests failed" % (f, t))
469 finally:
470 sys.stdout = save_stdout
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000471 if verbose:
Raymond Hettinger1ba24b42003-05-17 01:59:57 +0000472 print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t)
Raymond Hettinger35b34bd2003-05-17 00:58:33 +0000473 return f, t
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000474
475#=======================================================================
476# Threading support to prevent reporting refleaks when running regrtest.py -R
477
478def threading_setup():
479 import threading
480 return len(threading._active), len(threading._limbo)
481
482def threading_cleanup(num_active, num_limbo):
483 import threading
484 import time
485
486 _MAX_COUNT = 10
487 count = 0
488 while len(threading._active) != num_active and count < _MAX_COUNT:
489 count += 1
490 time.sleep(0.1)
491
492 count = 0
493 while len(threading._limbo) != num_limbo and count < _MAX_COUNT:
494 count += 1
495 time.sleep(0.1)
496
497def reap_children():
498 """Use this function at the end of test_main() whenever sub-processes
499 are started. This will help ensure that no extra children (zombies)
500 stick around to hog resources and create problems when looking
501 for refleaks.
502 """
503
504 # Reap all our dead child processes so we don't leave zombies around.
505 # These hog resources and might be causing some of the buildbots to die.
506 import os
507 if hasattr(os, 'waitpid'):
508 any_process = -1
509 while True:
510 try:
511 # This will raise an exception on Windows. That's ok.
512 pid, status = os.waitpid(any_process, os.WNOHANG)
513 if pid == 0:
514 break
515 except:
516 break