PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/SiRFLive/PythonStdLib/test/test_support.py

https://bitbucket.org/x893/sirflive
Python | 341 lines | 326 code | 8 blank | 7 comment | 7 complexity | cf51594c8a329a83dbece441445bc4b0 MD5 | raw file
  1. """Supporting definitions for the Python regression tests."""
  2. if __name__ != 'test.test_support':
  3. raise ImportError, 'test_support must be imported from the test package'
  4. import sys
  5. class Error(Exception):
  6. """Base class for regression test exceptions."""
  7. class TestFailed(Error):
  8. """Test failed."""
  9. class TestSkipped(Error):
  10. """Test skipped.
  11. This can be raised to indicate that a test was deliberatly
  12. skipped, but not because a feature wasn't available. For
  13. example, if some resource can't be used, such as the network
  14. appears to be unavailable, this should be raised instead of
  15. TestFailed.
  16. """
  17. class ResourceDenied(TestSkipped):
  18. """Test skipped because it requested a disallowed resource.
  19. This is raised when a test calls requires() for a resource that
  20. has not be enabled. It is used to distinguish between expected
  21. and unexpected skips.
  22. """
  23. verbose = 1 # Flag set to 0 by regrtest.py
  24. use_resources = None # Flag set to [] by regrtest.py
  25. # _original_stdout is meant to hold stdout at the time regrtest began.
  26. # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
  27. # The point is to have some flavor of stdout the user can actually see.
  28. _original_stdout = None
  29. def record_original_stdout(stdout):
  30. global _original_stdout
  31. _original_stdout = stdout
  32. def get_original_stdout():
  33. return _original_stdout or sys.stdout
  34. def unload(name):
  35. try:
  36. del sys.modules[name]
  37. except KeyError:
  38. pass
  39. def forget(modname):
  40. '''"Forget" a module was ever imported by removing it from sys.modules and
  41. deleting any .pyc and .pyo files.'''
  42. unload(modname)
  43. import os
  44. for dirname in sys.path:
  45. try:
  46. os.unlink(os.path.join(dirname, modname + os.extsep + 'pyc'))
  47. except os.error:
  48. pass
  49. # Deleting the .pyo file cannot be within the 'try' for the .pyc since
  50. # the chance exists that there is no .pyc (and thus the 'try' statement
  51. # is exited) but there is a .pyo file.
  52. try:
  53. os.unlink(os.path.join(dirname, modname + os.extsep + 'pyo'))
  54. except os.error:
  55. pass
  56. def is_resource_enabled(resource):
  57. """Test whether a resource is enabled. Known resources are set by
  58. regrtest.py."""
  59. return use_resources is not None and resource in use_resources
  60. def requires(resource, msg=None):
  61. """Raise ResourceDenied if the specified resource is not available.
  62. If the caller's module is __main__ then automatically return True. The
  63. possibility of False being returned occurs when regrtest.py is executing."""
  64. # see if the caller's module is __main__ - if so, treat as if
  65. # the resource was set
  66. if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
  67. return
  68. if not is_resource_enabled(resource):
  69. if msg is None:
  70. msg = "Use of the `%s' resource not enabled" % resource
  71. raise ResourceDenied(msg)
  72. def bind_port(sock, host='', preferred_port=54321):
  73. """Try to bind the sock to a port. If we are running multiple
  74. tests and we don't try multiple ports, the test can fails. This
  75. makes the test more robust."""
  76. import socket, errno
  77. # some random ports that hopefully no one is listening on.
  78. for port in [preferred_port, 9907, 10243, 32999]:
  79. try:
  80. sock.bind((host, port))
  81. return port
  82. except socket.error, (err, msg):
  83. if err != errno.EADDRINUSE:
  84. raise
  85. print >>sys.__stderr__, \
  86. ' WARNING: failed to listen on port %d, trying another' % port
  87. raise TestFailed, 'unable to find port to listen on'
  88. FUZZ = 1e-6
  89. def fcmp(x, y): # fuzzy comparison function
  90. if type(x) == type(0.0) or type(y) == type(0.0):
  91. try:
  92. x, y = coerce(x, y)
  93. fuzz = (abs(x) + abs(y)) * FUZZ
  94. if abs(x-y) <= fuzz:
  95. return 0
  96. except:
  97. pass
  98. elif type(x) == type(y) and type(x) in (type(()), type([])):
  99. for i in range(min(len(x), len(y))):
  100. outcome = fcmp(x[i], y[i])
  101. if outcome != 0:
  102. return outcome
  103. return cmp(len(x), len(y))
  104. return cmp(x, y)
  105. try:
  106. unicode
  107. have_unicode = 1
  108. except NameError:
  109. have_unicode = 0
  110. is_jython = sys.platform.startswith('java')
  111. import os
  112. # Filename used for testing
  113. if os.name == 'java':
  114. # Jython disallows @ in module names
  115. TESTFN = '$test'
  116. elif os.name == 'riscos':
  117. TESTFN = 'testfile'
  118. else:
  119. TESTFN = '@test'
  120. # Unicode name only used if TEST_FN_ENCODING exists for the platform.
  121. if have_unicode:
  122. # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding()
  123. # TESTFN_UNICODE is a filename that can be encoded using the
  124. # file system encoding, but *not* with the default (ascii) encoding
  125. if isinstance('', unicode):
  126. # python -U
  127. # XXX perhaps unicode() should accept Unicode strings?
  128. TESTFN_UNICODE = "@test-\xe0\xf2"
  129. else:
  130. # 2 latin characters.
  131. TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1")
  132. TESTFN_ENCODING = sys.getfilesystemencoding()
  133. # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
  134. # able to be encoded by *either* the default or filesystem encoding.
  135. # This test really only makes sense on Windows NT platforms
  136. # which have special Unicode support in posixmodule.
  137. if (not hasattr(sys, "getwindowsversion") or
  138. sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
  139. TESTFN_UNICODE_UNENCODEABLE = None
  140. else:
  141. # Japanese characters (I think - from bug 846133)
  142. TESTFN_UNICODE_UNENCODEABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
  143. try:
  144. # XXX - Note - should be using TESTFN_ENCODING here - but for
  145. # Windows, "mbcs" currently always operates as if in
  146. # errors=ignore' mode - hence we get '?' characters rather than
  147. # the exception. 'Latin1' operates as we expect - ie, fails.
  148. # See [ 850997 ] mbcs encoding ignores errors
  149. TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
  150. except UnicodeEncodeError:
  151. pass
  152. else:
  153. print \
  154. 'WARNING: The filename %r CAN be encoded by the filesystem. ' \
  155. 'Unicode filename tests may not be effective' \
  156. % TESTFN_UNICODE_UNENCODEABLE
  157. # Make sure we can write to TESTFN, try in /tmp if we can't
  158. fp = None
  159. try:
  160. fp = open(TESTFN, 'w+')
  161. except IOError:
  162. TMP_TESTFN = os.path.join('/tmp', TESTFN)
  163. try:
  164. fp = open(TMP_TESTFN, 'w+')
  165. TESTFN = TMP_TESTFN
  166. del TMP_TESTFN
  167. except IOError:
  168. print ('WARNING: tests will fail, unable to write to: %s or %s' %
  169. (TESTFN, TMP_TESTFN))
  170. if fp is not None:
  171. fp.close()
  172. try:
  173. os.unlink(TESTFN)
  174. except:
  175. pass
  176. del os, fp
  177. from os import unlink
  178. def findfile(file, here=__file__):
  179. """Try to find a file on sys.path and the working directory. If it is not
  180. found the argument passed to the function is returned (this does not
  181. necessarily signal failure; could still be the legitimate path)."""
  182. import os
  183. if os.path.isabs(file):
  184. return file
  185. path = sys.path
  186. path = [os.path.dirname(here)] + path
  187. for dn in path:
  188. fn = os.path.join(dn, file)
  189. if os.path.exists(fn): return fn
  190. return file
  191. def verify(condition, reason='test failed'):
  192. """Verify that condition is true. If not, raise TestFailed.
  193. The optional argument reason can be given to provide
  194. a better error text.
  195. """
  196. if not condition:
  197. raise TestFailed(reason)
  198. def vereq(a, b):
  199. """Raise TestFailed if a == b is false.
  200. This is better than verify(a == b) because, in case of failure, the
  201. error message incorporates repr(a) and repr(b) so you can see the
  202. inputs.
  203. Note that "not (a == b)" isn't necessarily the same as "a != b"; the
  204. former is tested.
  205. """
  206. if not (a == b):
  207. raise TestFailed, "%r == %r" % (a, b)
  208. def sortdict(dict):
  209. "Like repr(dict), but in sorted order."
  210. items = dict.items()
  211. items.sort()
  212. reprpairs = ["%r: %r" % pair for pair in items]
  213. withcommas = ", ".join(reprpairs)
  214. return "{%s}" % withcommas
  215. def check_syntax(statement):
  216. try:
  217. compile(statement, '<string>', 'exec')
  218. except SyntaxError:
  219. pass
  220. else:
  221. print 'Missing SyntaxError: "%s"' % statement
  222. #=======================================================================
  223. # Preliminary PyUNIT integration.
  224. import unittest
  225. class BasicTestRunner:
  226. def run(self, test):
  227. result = unittest.TestResult()
  228. test(result)
  229. return result
  230. def run_suite(suite, testclass=None):
  231. """Run tests from a unittest.TestSuite-derived class."""
  232. if verbose:
  233. runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
  234. else:
  235. runner = BasicTestRunner()
  236. result = runner.run(suite)
  237. if not result.wasSuccessful():
  238. if len(result.errors) == 1 and not result.failures:
  239. err = result.errors[0][1]
  240. elif len(result.failures) == 1 and not result.errors:
  241. err = result.failures[0][1]
  242. else:
  243. if testclass is None:
  244. msg = "errors occurred; run in verbose mode for details"
  245. else:
  246. msg = "errors occurred in %s.%s" \
  247. % (testclass.__module__, testclass.__name__)
  248. raise TestFailed(msg)
  249. raise TestFailed(err)
  250. def run_unittest(*classes):
  251. """Run tests from unittest.TestCase-derived classes."""
  252. suite = unittest.TestSuite()
  253. for cls in classes:
  254. if isinstance(cls, (unittest.TestSuite, unittest.TestCase)):
  255. suite.addTest(cls)
  256. else:
  257. suite.addTest(unittest.makeSuite(cls))
  258. if len(classes)==1:
  259. testclass = classes[0]
  260. else:
  261. testclass = None
  262. run_suite(suite, testclass)
  263. #=======================================================================
  264. # doctest driver.
  265. def run_doctest(module, verbosity=None):
  266. """Run doctest on the given module. Return (#failures, #tests).
  267. If optional argument verbosity is not specified (or is None), pass
  268. test_support's belief about verbosity on to doctest. Else doctest's
  269. usual behavior is used (it searches sys.argv for -v).
  270. """
  271. import doctest
  272. if verbosity is None:
  273. verbosity = verbose
  274. else:
  275. verbosity = None
  276. # Direct doctest output (normally just errors) to real stdout; doctest
  277. # output shouldn't be compared by regrtest.
  278. save_stdout = sys.stdout
  279. sys.stdout = get_original_stdout()
  280. try:
  281. f, t = doctest.testmod(module, verbose=verbosity)
  282. if f:
  283. raise TestFailed("%d of %d doctests failed" % (f, t))
  284. finally:
  285. sys.stdout = save_stdout
  286. if verbose:
  287. print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t)
  288. return f, t