PageRenderTime 22ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/tornado/test/runtests.py

https://github.com/ovidiucp/tornado
Python | 180 lines | 135 code | 18 blank | 27 comment | 17 complexity | 529f9a9cc19a513f61083c7e0b831a15 MD5 | raw file
  1. #!/usr/bin/env python
  2. from __future__ import absolute_import, division, print_function, with_statement
  3. import gc
  4. import locale # system locale module, not tornado.locale
  5. import logging
  6. import operator
  7. import textwrap
  8. import sys
  9. from tornado.httpclient import AsyncHTTPClient
  10. from tornado.httpserver import HTTPServer
  11. from tornado.ioloop import IOLoop
  12. from tornado.netutil import Resolver
  13. from tornado.options import define, options, add_parse_callback
  14. from tornado.test.util import unittest
  15. try:
  16. reduce # py2
  17. except NameError:
  18. from functools import reduce # py3
  19. TEST_MODULES = [
  20. 'tornado.httputil.doctests',
  21. 'tornado.iostream.doctests',
  22. 'tornado.util.doctests',
  23. 'tornado.test.asyncio_test',
  24. 'tornado.test.auth_test',
  25. 'tornado.test.concurrent_test',
  26. 'tornado.test.curl_httpclient_test',
  27. 'tornado.test.escape_test',
  28. 'tornado.test.gen_test',
  29. 'tornado.test.http1connection_test',
  30. 'tornado.test.httpclient_test',
  31. 'tornado.test.httpserver_test',
  32. 'tornado.test.httputil_test',
  33. 'tornado.test.import_test',
  34. 'tornado.test.ioloop_test',
  35. 'tornado.test.iostream_test',
  36. 'tornado.test.locale_test',
  37. 'tornado.test.locks_test',
  38. 'tornado.test.netutil_test',
  39. 'tornado.test.log_test',
  40. 'tornado.test.options_test',
  41. 'tornado.test.process_test',
  42. 'tornado.test.queues_test',
  43. 'tornado.test.simple_httpclient_test',
  44. 'tornado.test.stack_context_test',
  45. 'tornado.test.tcpclient_test',
  46. 'tornado.test.tcpserver_test',
  47. 'tornado.test.template_test',
  48. 'tornado.test.testing_test',
  49. 'tornado.test.twisted_test',
  50. 'tornado.test.util_test',
  51. 'tornado.test.web_test',
  52. 'tornado.test.websocket_test',
  53. 'tornado.test.wsgi_test',
  54. ]
  55. def all():
  56. return unittest.defaultTestLoader.loadTestsFromNames(TEST_MODULES)
  57. class TornadoTextTestRunner(unittest.TextTestRunner):
  58. def run(self, test):
  59. result = super(TornadoTextTestRunner, self).run(test)
  60. if result.skipped:
  61. skip_reasons = set(reason for (test, reason) in result.skipped)
  62. self.stream.write(textwrap.fill(
  63. "Some tests were skipped because: %s" %
  64. ", ".join(sorted(skip_reasons))))
  65. self.stream.write("\n")
  66. return result
  67. class LogCounter(logging.Filter):
  68. """Counts the number of WARNING or higher log records."""
  69. def __init__(self, *args, **kwargs):
  70. # Can't use super() because logging.Filter is an old-style class in py26
  71. logging.Filter.__init__(self, *args, **kwargs)
  72. self.warning_count = self.error_count = 0
  73. def filter(self, record):
  74. if record.levelno >= logging.ERROR:
  75. self.error_count += 1
  76. elif record.levelno >= logging.WARNING:
  77. self.warning_count += 1
  78. return True
  79. def main():
  80. # The -W command-line option does not work in a virtualenv with
  81. # python 3 (as of virtualenv 1.7), so configure warnings
  82. # programmatically instead.
  83. import warnings
  84. # Be strict about most warnings. This also turns on warnings that are
  85. # ignored by default, including DeprecationWarnings and
  86. # python 3.2's ResourceWarnings.
  87. warnings.filterwarnings("error")
  88. # setuptools sometimes gives ImportWarnings about things that are on
  89. # sys.path even if they're not being used.
  90. warnings.filterwarnings("ignore", category=ImportWarning)
  91. # Tornado generally shouldn't use anything deprecated, but some of
  92. # our dependencies do (last match wins).
  93. warnings.filterwarnings("ignore", category=DeprecationWarning)
  94. warnings.filterwarnings("error", category=DeprecationWarning,
  95. module=r"tornado\..*")
  96. warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
  97. warnings.filterwarnings("error", category=PendingDeprecationWarning,
  98. module=r"tornado\..*")
  99. # The unittest module is aggressive about deprecating redundant methods,
  100. # leaving some without non-deprecated spellings that work on both
  101. # 2.7 and 3.2
  102. warnings.filterwarnings("ignore", category=DeprecationWarning,
  103. message="Please use assert.* instead")
  104. # unittest2 0.6 on py26 reports these as PendingDeprecationWarnings
  105. # instead of DeprecationWarnings.
  106. warnings.filterwarnings("ignore", category=PendingDeprecationWarning,
  107. message="Please use assert.* instead")
  108. # Twisted 15.0.0 triggers some warnings on py3 with -bb.
  109. warnings.filterwarnings("ignore", category=BytesWarning,
  110. module=r"twisted\..*")
  111. logging.getLogger("tornado.access").setLevel(logging.CRITICAL)
  112. define('httpclient', type=str, default=None,
  113. callback=lambda s: AsyncHTTPClient.configure(
  114. s, defaults=dict(allow_ipv6=False)))
  115. define('httpserver', type=str, default=None,
  116. callback=HTTPServer.configure)
  117. define('ioloop', type=str, default=None)
  118. define('ioloop_time_monotonic', default=False)
  119. define('resolver', type=str, default=None,
  120. callback=Resolver.configure)
  121. define('debug_gc', type=str, multiple=True,
  122. help="A comma-separated list of gc module debug constants, "
  123. "e.g. DEBUG_STATS or DEBUG_COLLECTABLE,DEBUG_OBJECTS",
  124. callback=lambda values: gc.set_debug(
  125. reduce(operator.or_, (getattr(gc, v) for v in values))))
  126. define('locale', type=str, default=None,
  127. callback=lambda x: locale.setlocale(locale.LC_ALL, x))
  128. def configure_ioloop():
  129. kwargs = {}
  130. if options.ioloop_time_monotonic:
  131. from tornado.platform.auto import monotonic_time
  132. if monotonic_time is None:
  133. raise RuntimeError("monotonic clock not found")
  134. kwargs['time_func'] = monotonic_time
  135. if options.ioloop or kwargs:
  136. IOLoop.configure(options.ioloop, **kwargs)
  137. add_parse_callback(configure_ioloop)
  138. log_counter = LogCounter()
  139. add_parse_callback(
  140. lambda: logging.getLogger().handlers[0].addFilter(log_counter))
  141. import tornado.testing
  142. kwargs = {}
  143. if sys.version_info >= (3, 2):
  144. # HACK: unittest.main will make its own changes to the warning
  145. # configuration, which may conflict with the settings above
  146. # or command-line flags like -bb. Passing warnings=False
  147. # suppresses this behavior, although this looks like an implementation
  148. # detail. http://bugs.python.org/issue15626
  149. kwargs['warnings'] = False
  150. kwargs['testRunner'] = TornadoTextTestRunner
  151. try:
  152. tornado.testing.main(**kwargs)
  153. finally:
  154. # The tests should run clean; consider it a failure if they logged
  155. # any warnings or errors. We'd like to ban info logs too, but
  156. # we can't count them cleanly due to interactions with LogTrapTestCase.
  157. if log_counter.warning_count > 0 or log_counter.error_count > 0:
  158. logging.error("logged %d warnings and %d errors",
  159. log_counter.warning_count, log_counter.error_count)
  160. sys.exit(1)
  161. if __name__ == '__main__':
  162. main()