util.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import contextlib
  2. import os
  3. import platform
  4. import socket
  5. import sys
  6. import textwrap
  7. import typing # noqa: F401
  8. import unittest
  9. import warnings
  10. from tornado.testing import bind_unused_port
  11. skipIfNonUnix = unittest.skipIf(
  12. os.name != "posix" or sys.platform == "cygwin", "non-unix platform"
  13. )
  14. # travis-ci.org runs our tests in an overworked virtual machine, which makes
  15. # timing-related tests unreliable.
  16. skipOnTravis = unittest.skipIf(
  17. "TRAVIS" in os.environ, "timing tests unreliable on travis"
  18. )
  19. # Set the environment variable NO_NETWORK=1 to disable any tests that
  20. # depend on an external network.
  21. skipIfNoNetwork = unittest.skipIf("NO_NETWORK" in os.environ, "network access disabled")
  22. skipNotCPython = unittest.skipIf(
  23. platform.python_implementation() != "CPython", "Not CPython implementation"
  24. )
  25. # Used for tests affected by
  26. # https://bitbucket.org/pypy/pypy/issues/2616/incomplete-error-handling-in
  27. # TODO: remove this after pypy3 5.8 is obsolete.
  28. skipPypy3V58 = unittest.skipIf(
  29. platform.python_implementation() == "PyPy"
  30. and sys.version_info > (3,)
  31. and sys.pypy_version_info < (5, 9), # type: ignore
  32. "pypy3 5.8 has buggy ssl module",
  33. )
  34. def _detect_ipv6():
  35. if not socket.has_ipv6:
  36. # socket.has_ipv6 check reports whether ipv6 was present at compile
  37. # time. It's usually true even when ipv6 doesn't work for other reasons.
  38. return False
  39. sock = None
  40. try:
  41. sock = socket.socket(socket.AF_INET6)
  42. sock.bind(("::1", 0))
  43. except socket.error:
  44. return False
  45. finally:
  46. if sock is not None:
  47. sock.close()
  48. return True
  49. skipIfNoIPv6 = unittest.skipIf(not _detect_ipv6(), "ipv6 support not present")
  50. def refusing_port():
  51. """Returns a local port number that will refuse all connections.
  52. Return value is (cleanup_func, port); the cleanup function
  53. must be called to free the port to be reused.
  54. """
  55. # On travis-ci, port numbers are reassigned frequently. To avoid
  56. # collisions with other tests, we use an open client-side socket's
  57. # ephemeral port number to ensure that nothing can listen on that
  58. # port.
  59. server_socket, port = bind_unused_port()
  60. server_socket.setblocking(True)
  61. client_socket = socket.socket()
  62. client_socket.connect(("127.0.0.1", port))
  63. conn, client_addr = server_socket.accept()
  64. conn.close()
  65. server_socket.close()
  66. return (client_socket.close, client_addr[1])
  67. def exec_test(caller_globals, caller_locals, s):
  68. """Execute ``s`` in a given context and return the result namespace.
  69. Used to define functions for tests in particular python
  70. versions that would be syntax errors in older versions.
  71. """
  72. # Flatten the real global and local namespace into our fake
  73. # globals: it's all global from the perspective of code defined
  74. # in s.
  75. global_namespace = dict(caller_globals, **caller_locals) # type: ignore
  76. local_namespace = {} # type: typing.Dict[str, typing.Any]
  77. exec(textwrap.dedent(s), global_namespace, local_namespace)
  78. return local_namespace
  79. def subTest(test, *args, **kwargs):
  80. """Compatibility shim for unittest.TestCase.subTest.
  81. Usage: ``with tornado.test.util.subTest(self, x=x):``
  82. """
  83. try:
  84. subTest = test.subTest # py34+
  85. except AttributeError:
  86. subTest = contextlib.contextmanager(lambda *a, **kw: (yield))
  87. return subTest(*args, **kwargs)
  88. @contextlib.contextmanager
  89. def ignore_deprecation():
  90. """Context manager to ignore deprecation warnings."""
  91. with warnings.catch_warnings():
  92. warnings.simplefilter("ignore", DeprecationWarning)
  93. yield