1 """Supporting definitions for the Python regression tests."""
3 if __name__
!= 'test.test_support':
4 raise ImportError, 'test_support must be imported from the test package'
8 class Error(Exception):
9 """Base class for regression test exceptions."""
11 class TestFailed(Error
):
14 class TestSkipped(Error
):
17 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
24 class ResourceDenied(TestSkipped
):
25 """Test skipped because it requested a disallowed resource.
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
32 verbose
= 1 # Flag set to 0 by regrtest.py
33 use_resources
= None # Flag set to [] by regrtest.py
34 max_memuse
= 0 # Disable bigmem tests (they will still be run with
35 # small sizes, to make sure they work.)
37 # _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
41 def record_original_stdout(stdout
):
42 global _original_stdout
43 _original_stdout
= stdout
45 def get_original_stdout():
46 return _original_stdout
or sys
.stdout
62 '''"Forget" a module was ever imported by removing it from sys.modules and
63 deleting any .pyc and .pyo files.'''
66 for dirname
in sys
.path
:
67 unlink(os
.path
.join(dirname
, modname
+ os
.extsep
+ 'pyc'))
68 # 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.
71 unlink(os
.path
.join(dirname
, modname
+ os
.extsep
+ 'pyo'))
73 def is_resource_enabled(resource
):
74 """Test whether a resource is enabled. Known resources are set by
76 return use_resources
is not None and resource
in use_resources
78 def requires(resource
, msg
=None):
79 """Raise ResourceDenied if the specified resource is not available.
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."""
83 # 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__":
87 if not is_resource_enabled(resource
):
89 msg
= "Use of the `%s' resource not enabled" % resource
90 raise ResourceDenied(msg
)
94 def fcmp(x
, y
): # fuzzy comparison function
95 if type(x
) == type(0.0) or type(y
) == type(0.0):
98 fuzz
= (abs(x
) + abs(y
)) * FUZZ
103 elif type(x
) == type(y
) and type(x
) in (type(()), type([])):
104 for i
in range(min(len(x
), len(y
))):
105 outcome
= fcmp(x
[i
], y
[i
])
108 return cmp(len(x
), len(y
))
117 is_jython
= sys
.platform
.startswith('java')
120 # Filename used for testing
121 if os
.name
== 'java':
122 # Jython disallows @ in module names
124 elif os
.name
== 'riscos':
128 # Unicode name only used if TEST_FN_ENCODING exists for the platform.
130 # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
131 # TESTFN_UNICODE is a filename that can be encoded using the
132 # file system encoding, but *not* with the default (ascii) encoding
133 if isinstance('', unicode):
135 # XXX perhaps unicode() should accept Unicode strings?
136 TESTFN_UNICODE
= "@test-\xe0\xf2"
138 # 2 latin characters.
139 TESTFN_UNICODE
= unicode("@test-\xe0\xf2", "latin-1")
140 TESTFN_ENCODING
= sys
.getfilesystemencoding()
141 # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
142 # able to be encoded by *either* the default or filesystem encoding.
143 # This test really only makes sense on Windows NT platforms
144 # which have special Unicode support in posixmodule.
145 if (not hasattr(sys
, "getwindowsversion") or
146 sys
.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
147 TESTFN_UNICODE_UNENCODEABLE
= None
149 # Japanese characters (I think - from bug 846133)
150 TESTFN_UNICODE_UNENCODEABLE
= eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
152 # XXX - Note - should be using TESTFN_ENCODING here - but for
153 # Windows, "mbcs" currently always operates as if in
154 # errors=ignore' mode - hence we get '?' characters rather than
155 # the exception. 'Latin1' operates as we expect - ie, fails.
156 # See [ 850997 ] mbcs encoding ignores errors
157 TESTFN_UNICODE_UNENCODEABLE
.encode("Latin1")
158 except UnicodeEncodeError:
162 'WARNING: The filename %r CAN be encoded by the filesystem. ' \
163 'Unicode filename tests may not be effective' \
164 % TESTFN_UNICODE_UNENCODEABLE
166 # Make sure we can write to TESTFN, try in /tmp if we can't
169 fp
= open(TESTFN
, 'w+')
171 TMP_TESTFN
= os
.path
.join('/tmp', TESTFN
)
173 fp
= open(TMP_TESTFN
, 'w+')
177 print ('WARNING: tests will fail, unable to write to: %s or %s' %
178 (TESTFN
, TMP_TESTFN
))
184 def findfile(file, here
=__file__
):
185 """Try to find a file on sys.path and the working directory. If it is not
186 found the argument passed to the function is returned (this does not
187 necessarily signal failure; could still be the legitimate path)."""
189 if os
.path
.isabs(file):
192 path
= [os
.path
.dirname(here
)] + path
194 fn
= os
.path
.join(dn
, file)
195 if os
.path
.exists(fn
): return fn
198 def verify(condition
, reason
='test failed'):
199 """Verify that condition is true. If not, raise TestFailed.
201 The optional argument reason can be given to provide
206 raise TestFailed(reason
)
209 """Raise TestFailed if a == b is false.
211 This is better than verify(a == b) because, in case of failure, the
212 error message incorporates repr(a) and repr(b) so you can see the
215 Note that "not (a == b)" isn't necessarily the same as "a != b"; the
220 raise TestFailed
, "%r == %r" % (a
, b
)
223 "Like repr(dict), but in sorted order."
226 reprpairs
= ["%r: %r" % pair
for pair
in items
]
227 withcommas
= ", ".join(reprpairs
)
228 return "{%s}" % withcommas
230 def check_syntax(statement
):
232 compile(statement
, '<string>', 'exec')
236 print 'Missing SyntaxError: "%s"' % statement
238 def open_urlresource(url
):
239 import urllib
, urlparse
242 filename
= urlparse
.urlparse(url
)[2].split('/')[-1] # '/': it's URL!
244 for path
in [os
.path
.curdir
, os
.path
.pardir
]:
245 fn
= os
.path
.join(path
, filename
)
246 if os
.path
.exists(fn
):
250 print >> get_original_stdout(), '\tfetching %s ...' % url
251 fn
, _
= urllib
.urlretrieve(url
, filename
)
254 #=======================================================================
255 # Decorator for running a function in a different locale, correctly resetting
258 def run_with_locale(catstr
, *locales
):
260 def inner(*args
, **kwds
):
263 category
= getattr(locale
, catstr
)
264 orig_locale
= locale
.setlocale(category
)
265 except AttributeError:
266 # if the test author gives us an invalid category string
269 # cannot retrieve original locale, so do nothing
270 locale
= orig_locale
= None
274 locale
.setlocale(category
, loc
)
279 # now run the function, resetting the locale on exceptions
281 return func(*args
, **kwds
)
283 if locale
and orig_locale
:
284 locale
.setlocale(category
, orig_locale
)
285 inner
.func_name
= func
.func_name
286 inner
.__doc
__ = func
.__doc
__
290 #=======================================================================
291 # Big-memory-test support. Separate from 'resources' because memory use should be configurable.
293 # Some handy shorthands. Note that these are used for byte-limits as well
294 # as size-limits, in the various bigmem tests
299 def set_memlimit(limit
):
308 m
= re
.match(r
'(\d+(\.\d+)?) (K|M|G|T)b?$', limit
,
309 re
.IGNORECASE | re
.VERBOSE
)
311 raise ValueError('Invalid memory limit %r' % (limit
,))
312 memlimit
= int(float(m
.group(1)) * sizes
[m
.group(3).lower()])
313 if memlimit
< 2.5*_1G
:
314 raise ValueError('Memory limit %r too low to be useful' % (limit
,))
315 max_memuse
= memlimit
317 def bigmemtest(minsize
, memuse
, overhead
=5*_1M
):
318 """Decorator for bigmem tests.
320 'minsize' is the minimum useful size for the test (in arbitrary,
321 test-interpreted units.) 'memuse' is the number of 'bytes per size' for
322 the test, or a good estimate of it. 'overhead' specifies fixed overhead,
323 independant of the testsize, and defaults to 5Mb.
325 The decorator tries to guess a good value for 'size' and passes it to
326 the decorated test function. If minsize * memuse is more than the
327 allowed memory use (as defined by max_memuse), the test is skipped.
328 Otherwise, minsize is adjusted upward to use up to max_memuse.
333 # If max_memuse is 0 (the default),
334 # we still want to run the tests with size set to a few kb,
335 # to make sure they work. We still want to avoid using
336 # too much memory, though, but we do that noisily.
338 self
.failIf(maxsize
* memuse
+ overhead
> 20 * _1M
)
340 maxsize
= int((max_memuse
- overhead
) / memuse
)
341 if maxsize
< minsize
:
342 # Really ought to print 'test skipped' or something
344 sys
.stderr
.write("Skipping %s because of memory "
345 "constraint\n" % (f
.__name
__,))
347 # Try to keep some breathing room in memory use
348 maxsize
= max(maxsize
- 50 * _1M
, minsize
)
349 return f(self
, maxsize
)
350 wrapper
.minsize
= minsize
351 wrapper
.memuse
= memuse
352 wrapper
.overhead
= overhead
356 #=======================================================================
357 # Preliminary PyUNIT integration.
362 class BasicTestRunner
:
364 result
= unittest
.TestResult()
369 def run_suite(suite
, testclass
=None):
370 """Run tests from a unittest.TestSuite-derived class."""
372 runner
= unittest
.TextTestRunner(sys
.stdout
, verbosity
=2)
374 runner
= BasicTestRunner()
376 result
= runner
.run(suite
)
377 if not result
.wasSuccessful():
378 if len(result
.errors
) == 1 and not result
.failures
:
379 err
= result
.errors
[0][1]
380 elif len(result
.failures
) == 1 and not result
.errors
:
381 err
= result
.failures
[0][1]
383 if testclass
is None:
384 msg
= "errors occurred; run in verbose mode for details"
386 msg
= "errors occurred in %s.%s" \
387 % (testclass
.__module
__, testclass
.__name
__)
388 raise TestFailed(msg
)
389 raise TestFailed(err
)
392 def run_unittest(*classes
):
393 """Run tests from unittest.TestCase-derived classes."""
394 suite
= unittest
.TestSuite()
396 if isinstance(cls
, (unittest
.TestSuite
, unittest
.TestCase
)):
399 suite
.addTest(unittest
.makeSuite(cls
))
401 testclass
= classes
[0]
404 run_suite(suite
, testclass
)
407 #=======================================================================
410 def run_doctest(module
, verbosity
=None):
411 """Run doctest on the given module. Return (#failures, #tests).
413 If optional argument verbosity is not specified (or is None), pass
414 test_support's belief about verbosity on to doctest. Else doctest's
415 usual behavior is used (it searches sys.argv for -v).
420 if verbosity
is None:
425 # Direct doctest output (normally just errors) to real stdout; doctest
426 # output shouldn't be compared by regrtest.
427 save_stdout
= sys
.stdout
428 sys
.stdout
= get_original_stdout()
430 f
, t
= doctest
.testmod(module
, verbose
=verbosity
)
432 raise TestFailed("%d of %d doctests failed" % (f
, t
))
434 sys
.stdout
= save_stdout
436 print 'doctest (%s) ... %d tests with zero failures' % (module
.__name
__, t
)