1# Copyright (c) 2018 gevent community 2# 3# Permission is hereby granted, free of charge, to any person obtaining a copy 4# of this software and associated documentation files (the "Software"), to deal 5# in the Software without restriction, including without limitation the rights 6# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7# copies of the Software, and to permit persons to whom the Software is 8# furnished to do so, subject to the following conditions: 9# 10# The above copyright notice and this permission notice shall be included in 11# all copies or substantial portions of the Software. 12# 13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19# THE SOFTWARE. 20from __future__ import absolute_import, print_function, division 21 22import functools 23import unittest 24 25from . import sysinfo 26 27def _identity(f): 28 return f 29 30def _do_not_skip(reason): 31 assert reason 32 return _identity 33 34 35skipOnMac = _do_not_skip 36skipOnMacOnCI = _do_not_skip 37skipOnWindows = _do_not_skip 38skipOnAppVeyor = _do_not_skip 39skipOnCI = _do_not_skip 40skipOnManylinux = _do_not_skip 41 42skipOnPyPy = _do_not_skip 43skipOnPyPyOnCI = _do_not_skip 44skipOnPyPy3OnCI = _do_not_skip 45skipOnPyPy3 = _do_not_skip 46skipOnPyPyOnWindows = _do_not_skip 47 48skipOnPy2 = unittest.skip if sysinfo.PY2 else _do_not_skip 49skipOnPy3 = unittest.skip if sysinfo.PY3 else _do_not_skip 50skipOnPy37 = unittest.skip if sysinfo.PY37 else _do_not_skip 51skipOnPy310 = unittest.skip if sysinfo.PY310 else _do_not_skip 52 53skipOnPurePython = unittest.skip if sysinfo.PURE_PYTHON else _do_not_skip 54skipWithCExtensions = unittest.skip if not sysinfo.PURE_PYTHON else _do_not_skip 55 56skipOnLibuv = _do_not_skip 57skipOnLibuvOnWin = _do_not_skip 58skipOnLibuvOnCI = _do_not_skip 59skipOnLibuvOnCIOnPyPy = _do_not_skip 60skipOnLibuvOnPyPyOnWin = _do_not_skip 61skipOnLibuvOnTravisOnCPython27 = _do_not_skip 62 63skipOnLibev = _do_not_skip 64 65if sysinfo.WIN: 66 skipOnWindows = unittest.skip 67 68if sysinfo.OSX: 69 skipOnMac = unittest.skip 70 71if sysinfo.RUNNING_ON_APPVEYOR: 72 # See comments scattered around about timeouts and the timer 73 # resolution available on appveyor (lots of jitter). this 74 # seems worse with the 62-bit builds. 75 # Note that we skip/adjust these tests only on AppVeyor, not 76 # win32---we don't think there's gevent related problems but 77 # environment related problems. These can be tested and debugged 78 # separately on windows in a more stable environment. 79 skipOnAppVeyor = unittest.skip 80 81 82if sysinfo.RUNNING_ON_CI: 83 skipOnCI = unittest.skip 84 if sysinfo.OSX: 85 skipOnMacOnCI = unittest.skip 86 87if sysinfo.RUNNING_ON_MANYLINUX: 88 skipOnManylinux = unittest.skip 89 90if sysinfo.PYPY: 91 skipOnPyPy = unittest.skip 92 if sysinfo.RUNNING_ON_CI: 93 skipOnPyPyOnCI = unittest.skip 94 95 if sysinfo.WIN: 96 skipOnPyPyOnWindows = unittest.skip 97 98 if sysinfo.PYPY3: 99 skipOnPyPy3 = unittest.skip 100 if sysinfo.RUNNING_ON_CI: 101 # Same as above, for PyPy3.3-5.5-alpha and 3.5-5.7.1-beta and 3.5-5.8 102 skipOnPyPy3OnCI = unittest.skip 103 104 105skipUnderCoverage = unittest.skip if sysinfo.RUN_COVERAGE else _do_not_skip 106 107skipIf = unittest.skipIf 108skipUnless = unittest.skipUnless 109 110_has_psutil_process = None 111def _check_psutil(): 112 global _has_psutil_process 113 if _has_psutil_process is None: 114 _has_psutil_process = sysinfo.get_this_psutil_process() is not None 115 return _has_psutil_process 116 117 118def _make_runtime_skip_decorator(reason, predicate): 119 def decorator(test_item): 120 if not isinstance(test_item, type): 121 f = test_item 122 @functools.wraps(test_item) 123 def skip_wrapper(*args, **kwargs): 124 if not predicate(): 125 raise unittest.SkipTest(reason) 126 return f(*args, **kwargs) 127 test_item = skip_wrapper 128 else: 129 # given a class, override setUp() to skip it. 130 # 131 # Internally, unittest uses two flags on the class to do this: 132 # __unittest_skip__ and __unittest_skip_why__. It *appears* 133 # these are evaluated for each method in the test, so we can safely 134 # change them at runtime. **This isn't documented.** 135 # 136 # If they are set before execution begins, then the class setUpClass 137 # and tearDownClass are skipped. So changing them at runtime could result 138 # in something being set up but not torn down. It is substantially 139 # faster, though, to set them. 140 base = test_item 141 base_setUp = base.setUp 142 @functools.wraps(test_item) 143 def setUp(self): 144 if not predicate(): 145 base.__unittest_skip__ = True 146 base.__unittest_skip_why__ = reason 147 raise unittest.SkipTest(reason) 148 base_setUp(self) 149 base.setUp = setUp 150 151 return test_item 152 153 return decorator 154 155def skipWithoutPSUtil(reason): 156 reason = "psutil not available: " + reason 157 # Defer the check until runtime to avoid imports 158 return _make_runtime_skip_decorator(reason, _check_psutil) 159 160if sysinfo.LIBUV: 161 skipOnLibuv = unittest.skip 162 163 if sysinfo.RUNNING_ON_CI: 164 skipOnLibuvOnCI = unittest.skip 165 if sysinfo.PYPY: 166 skipOnLibuvOnCIOnPyPy = unittest.skip 167 if sysinfo.RUNNING_ON_TRAVIS: 168 if sysinfo.CPYTHON: 169 if sysinfo.PY27_ONLY: 170 skipOnLibuvOnTravisOnCPython27 = unittest.skip 171 172 if sysinfo.WIN: 173 skipOnLibuvOnWin = unittest.skip 174 if sysinfo.PYPY: 175 skipOnLibuvOnPyPyOnWin = unittest.skip 176else: 177 skipOnLibev = unittest.skip 178 179 180def skipWithoutResource(resource, reason=''): 181 requires = 'Requires resource %r' % (resource,) 182 if not reason: 183 reason = requires 184 else: 185 reason = reason + ' (' + requires + ')' 186 187 # Defer until runtime; resources are established as part 188 # of test startup. 189 def predicate(): # This is easily cached if needed 190 from . import resources 191 return resources.ensure_setup_resources().is_resource_enabled(resource) 192 193 return _make_runtime_skip_decorator(reason, predicate) 194 195def skipWithoutExternalNetwork(reason=''): 196 # Use to decorate test functions or classes that 197 # need access to external network resources (e.g., DNS, HTTP servers, etc) 198 # 199 # Important: If you use this on classes, you must not use the 200 # two-argument form of super() 201 202 return skipWithoutResource('network', reason) 203