Commit a2c56938 authored by Jason Madden's avatar Jason Madden Committed by GitHub

Merge pull request #1309 from gevent/issue1293

Refactoring greentest
parents a8c1f171 b77e9acd
......@@ -12,12 +12,11 @@ omit =
src/gevent/_ssl2.py
src/gevent/libev/_corecffi_build.py
src/gevent/libuv/_corecffi_build.py
src/gevent/win32util.py
src/gevent/win32util.py
# having concurrency=greenlet means that the Queue class
# which is used from multiple real threads doesn't
# properly get covered.
src/gevent/_threading.py
test_*
src/gevent/_threading.py
# local.so sometimes gets included, and it can't be parsed
# as source, so it fails the whole process.
*.so
......@@ -43,3 +42,4 @@ omit =
# as source, so it fails the whole process.
# coverage 4.5 needs this specified here, 4.4.2 needed it in [run]
*.so
/tmp/test_*
......@@ -35,9 +35,9 @@ Makefile.ext
MANIFEST
*_flymake.py
src/greentest/.coverage\.*
src/greentest/htmlcov
src/greentest/.coverage
.coverage\.*
htmlcov/
.coverage
doc/_build
doc/__pycache__
......
......@@ -98,7 +98,7 @@ ignored-classes=SSLContext, SSLSocket, greenlet, Greenlet, parent, dead
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=gevent._corecffi,gevent.os,os,greenlet,threading,gevent.libev.corecffi
ignored-modules=gevent._corecffi,gevent.os,os,greenlet,threading,gevent.libev.corecffi,gevent.socket,gevent.core
[DESIGN]
max-attributes=12
......
......@@ -9,6 +9,11 @@ env:
global:
- BUILD_RUNTIMES=$HOME/.runtimes
- PYTHONHASHSEED=random
- CC="ccache gcc"
- CCACHE_NOCPP2=true
- CCACHE_SLOPPINESS=file_macro,time_macros,include_file_ctime,include_file_mtime
- CCACHE_NOHASHDIR=true
- CFLAGS="-g -pipe"
matrix:
# These are ordered to get as much diversity in the
......@@ -38,7 +43,7 @@ cache:
- $HOME/.venv
- $HOME/.runtimes
- $HOME/.wheelhouse
- $HOME/.ccache
before_cache:
- rm -f $HOME/.cache/pip/log/debug.log
......@@ -42,6 +42,10 @@
Objects/tupleobject.c: bad argument to internal function``. Reported
in :issue:`1302` by Ulrich Petri.
- Refactored the gevent test runner and test suite to make them more
reusable. In particular, the tests are now run with ``python -m
gevent.tests``. See :issue:`1293`.
1.3.7 (2018-10-12)
==================
......
......@@ -22,7 +22,7 @@ clean:
rm -rf src/gevent/libev/*.o src/gevent/libuv/*.o src/gevent/*.o
rm -rf src/gevent/__pycache__ src/greentest/__pycache__ src/greentest/greentest/__pycache__ src/gevent/libev/__pycache__
rm -rf src/gevent/*.pyc src/greentest/*.pyc src/gevent/libev/*.pyc
rm -rf src/greentest/htmlcov src/greentest/.coverage
rm -rf htmlcov .coverage
rm -rf build
distclean: clean
......@@ -33,8 +33,6 @@ distclean: clean
doc:
cd doc && PYTHONPATH=.. make html
whitespace:
! find . -not -path "*.pem" -not -path "./.eggs/*" -not -path "./src/greentest/htmlcov/*" -not -path "./src/greentest/.coverage.*" -not -path "./.tox/*" -not -path "*/__pycache__/*" -not -path "*.so" -not -path "*.pyc" -not -path "./.git/*" -not -path "./build/*" -not -path "./src/gevent/libev/*" -not -path "./src/gevent.egg-info/*" -not -path "./dist/*" -not -path "./.DS_Store" -not -path "./deps/*" -not -path "./src/gevent/libev/corecext.*.[ch]" -not -path "./src/gevent/resolver/cares.*" -not -path "./doc/_build/*" -not -path "./doc/mytheme/static/*" -type f | xargs egrep -l " $$"
prospector:
which pylint
......@@ -59,28 +57,25 @@ test_prelim:
basictest: test_prelim
@${PYTHON} scripts/travis.py fold_start basictest "Running basic tests"
cd src/greentest && GEVENT_RESOLVER=thread ${PYTHON} testrunner.py --config known_failures.py --quiet
GEVENT_RESOLVER=thread ${PYTHON} -mgevent.tests --config known_failures.py --quiet
@${PYTHON} scripts/travis.py fold_end basictest
alltest: basictest
@${PYTHON} scripts/travis.py fold_start ares "Running c-ares tests"
cd src/greentest && GEVENT_RESOLVER=ares ${PYTHON} testrunner.py --config known_failures.py --ignore tests_that_dont_use_resolver.txt --quiet
GEVENT_RESOLVER=ares ${PYTHON} -mgevent.tests --config known_failures.py --ignore tests_that_dont_use_resolver.txt --quiet
@${PYTHON} scripts/travis.py fold_end ares
@${PYTHON} scripts/travis.py fold_start dnspython "Running dnspython tests"
cd src/greentest && GEVENT_RESOLVER=dnspython ${PYTHON} testrunner.py --config known_failures.py --ignore tests_that_dont_use_resolver.txt --quiet
GEVENT_RESOLVER=dnspython ${PYTHON} -mgevent.tests --config known_failures.py --ignore tests_that_dont_use_resolver.txt --quiet
@${PYTHON} scripts/travis.py fold_end dnspython
# In the past, we included all test files that had a reference to 'subprocess'' somewhere in their
# text. The monkey-patched stdlib tests were specifically included here.
# However, we now always also test on AppVeyor (Windows) which only has GEVENT_FILE=thread,
# so we can save a lot of CI time by reducing the set and excluding the stdlib tests without
# losing any coverage. See the `threadfiletest` for what command used to run.
# losing any coverage.
@${PYTHON} scripts/travis.py fold_start thread "Running GEVENT_FILE=thread tests"
cd src/greentest && GEVENT_FILE=thread ${PYTHON} testrunner.py --config known_failures.py test__*subprocess*.py --quiet
cd src/gevent/tests && GEVENT_FILE=thread ${PYTHON} -mgevent.tests --config known_failures.py test__*subprocess*.py --quiet
@${PYTHON} scripts/travis.py fold_end thread
threadfiletest:
cd src/greentest && GEVENT_FILE=thread ${PYTHON} testrunner.py --config known_failures.py `grep -l subprocess test_*.py` --quiet
allbackendtest:
@${PYTHON} scripts/travis.py fold_start default "Testing default backend"
GEVENTTEST_COVERAGE=1 make alltest
......@@ -101,7 +96,7 @@ cffibackendtest:
leaktest: test_prelim
@${PYTHON} scripts/travis.py fold_start leaktest "Running leak tests"
cd src/greentest && GEVENT_RESOLVER=thread GEVENTTEST_LEAKCHECK=1 ${PYTHON} testrunner.py --config known_failures.py --quiet --ignore tests_that_dont_do_leakchecks.txt
GEVENT_RESOLVER=thread GEVENTTEST_LEAKCHECK=1 ${PYTHON} -mgevent.tests --config known_failures.py --quiet --ignore tests_that_dont_do_leakchecks.txt
@${PYTHON} scripts/travis.py fold_end leaktest
@${PYTHON} scripts/travis.py fold_start default "Testing default backend pure python"
PURE_PYTHON=1 GEVENTTEST_COVERAGE=1 make basictest
......@@ -116,8 +111,9 @@ travis_test_linters:
make cffibackendtest
coverage_combine:
coverage combine . src/greentest/
-coveralls --rcfile=src/greentest/.coveragerc
coverage combine .
coverage report -i
-coveralls
.PHONY: clean doc prospector lint travistest travis
......@@ -191,7 +187,7 @@ test-py34: $(PY34)
PYTHON=python3.4.8 PATH=$(BUILD_RUNTIMES)/versions/python3.4.8/bin:$(PATH) make develop basictest
test-py35: $(PY35)
PYTHON=python3.5.5 PATH=$(BUILD_RUNTIMES)/versions/python3.5.5/bin:$(PATH) make develop basictest
PYTHON=python3.5.5 PATH=$(BUILD_RUNTIMES)/versions/python3.5.5/bin:$(PATH) GEVENTTEST_COVERAGE=1 make develop basictest coverage_combine
test-py36: $(PY36)
PYTHON=python3.6.7 PATH=$(BUILD_RUNTIMES)/versions/python3.6.7/bin:$(PATH) make develop lint basictest
......
......@@ -138,23 +138,13 @@ cache:
- '%LOCALAPPDATA%\pip\Cache'
build_script:
# Build the compiled extension. First we make an sdist, then
# we install from that, to test sdist building issues. Finally we
# build a wheel for downloading purposes
- "%CMD_IN_ENV% %PYEXE% setup.py sdist --formats=gztar"
- ps: "ls dist"
# Now install the sdist.
# I couldn't get wildcards to work for pip install, so stuff it
# into a variable, using python to glob.
- "%PYEXE% -c \"import glob; print(glob.glob('dist/*gz')[0])\" > whl.txt"
- set /p PYWHL=<whl.txt
- "%PYEXE% -m pip install -U --upgrade-strategy=eager %PYWHL%[test,events,dnspython]"
- "%PYEXE% -m pip install -U --upgrade-strategy=eager -e .[test,events,dnspython]"
test_script:
# Run the project tests
- "%PYEXE% -c \"import gevent.core; print(gevent.core.loop)\""
- "%PYEXE% -c \"import gevent; print(gevent.config.settings['resolver'].get_options())\""
- "cd src/greentest && %PYEXE% testrunner.py --config known_failures.py --quiet && cd ../.."
- "%PYEXE% -mgevent.tests --config known_failures.py --quiet"
after_test:
- "%CMD_IN_ENV% %PYEXE% setup.py bdist_wheel"
......
......@@ -177,8 +177,7 @@ tests on one version of Python during development, begin with the
above instructions to install gevent in a virtual environment and then
run::
(env) $ cd src/greentest
(env) $ python ./testrunner.py
(env) $ python -mgevent.tests
Before submitting a pull request, it's a good idea to run the tests
across all supported versions of Python, and to check the code quality
......@@ -192,8 +191,7 @@ The testrunner accepts a ``--coverage`` argument to enable code
coverage metrics through the `coverage.py`_ package. That would go
something like this::
cd src/greentest
python testrunner.py --coverage
python -m gevent.tests --coverage
coverage combine
coverage html -i
<open htmlcov/index.html>
......
......@@ -373,7 +373,7 @@ def run_setup(ext_modules, run_make):
# We don't run coverage on Windows, and pypy can't build it there
# anyway (coveralls -> cryptopgraphy -> openssl)
'coverage>=4.0 ; sys_platform != "win32"',
'coverage>=5.0a3 ; sys_platform != "win32"',
'coveralls>=1.0 ; sys_platform != "win32"',
'futures ; python_version == "2.7"',
......
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
# Nothing public here
__all__ = []
......@@ -5,6 +5,10 @@ import sys
from gevent.libev import _corecffi # pylint:disable=no-name-in-module,import-error
# Nothing public here
__all__ = []
ffi = _corecffi.ffi # pylint:disable=no-member
libev = _corecffi.lib # pylint:disable=no-member
......
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
# Nothing public here
__all__ = []
......@@ -7,6 +7,9 @@ import sys
from gevent.libuv import _corecffi # pylint:disable=no-name-in-module,import-error
# Nothing public here
__all__ = []
ffi = _corecffi.ffi
libuv = _corecffi.lib
......
......@@ -16,6 +16,8 @@ from gevent.socket import EAI_SERVICE
from gevent.socket import AF_INET
from gevent.socket import AI_PASSIVE
# Nothing public here.
__all__ = []
def _lookup_port(port, socktype):
# pylint:disable=too-many-branches
......
......@@ -2,6 +2,10 @@
import _socket
__all__ = [
'Resolver',
]
class Resolver(object):
"""
A resolver that directly uses the system's resolver functions.
......
......@@ -75,8 +75,8 @@ from _socket import AF_UNSPEC
import socket
from . import AbstractResolver
from . import hostname_types
from gevent.resolver import AbstractResolver
from gevent.resolver import hostname_types
from gevent._compat import string_types
from gevent._compat import iteritems
......
......@@ -3,7 +3,14 @@
.. deprecated:: 1.3
Use :mod:`gevent.resolver.ares`
"""
import warnings
warnings.warn(
"gevent.resolver_ares is deprecated and will be removed in 1.5. "
"Use gevent.resolver.ares instead.",
DeprecationWarning,
stacklevel=2
)
del warnings
from gevent.resolver.ares import * # pylint:disable=wildcard-import,unused-wildcard-import
import gevent.resolver.ares as _ares
__all__ = _ares.__all__
......
"""Backwards compatibility alias for :mod:`gevent.resolver.thread`.
.. deprecated:: 1.3
Use :mod:`gevent.resolver.cares`
Use :mod:`gevent.resolver.thread`
"""
import warnings
warnings.warn(
"gevent.resolver_thread is deprecated and will be removed in 1.5. "
"Use gevent.resolver.thread instead.",
DeprecationWarning,
stacklevel=2
)
del warnings
from gevent.resolver.thread import * # pylint:disable=wildcard-import,unused-wildcard-import
import gevent.resolver.thread as _thread
__all__ = _thread.__all__
......
......@@ -20,106 +20,107 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# package is named greentest, not test, so it won't be confused with test in stdlib
import unittest
# pylint:disable=unused-import
from greentest.sysinfo import VERBOSE
from greentest.sysinfo import WIN
from greentest.sysinfo import LINUX
from greentest.sysinfo import LIBUV
from greentest.sysinfo import CFFI_BACKEND
from greentest.sysinfo import DEBUG
from greentest.sysinfo import RUN_LEAKCHECKS
from greentest.sysinfo import RUN_COVERAGE
from .sysinfo import VERBOSE
from .sysinfo import WIN
from .sysinfo import LINUX
from .sysinfo import LIBUV
from .sysinfo import CFFI_BACKEND
from .sysinfo import DEBUG
from .sysinfo import RUN_LEAKCHECKS
from .sysinfo import RUN_COVERAGE
from greentest.sysinfo import PY2
from greentest.sysinfo import PY3
from greentest.sysinfo import PY34
from greentest.sysinfo import PY36
from greentest.sysinfo import PY37
from .sysinfo import PY2
from .sysinfo import PY3
from .sysinfo import PY34
from .sysinfo import PY36
from .sysinfo import PY37
from greentest.sysinfo import PYPY
from greentest.sysinfo import PYPY3
from greentest.sysinfo import CPYTHON
from .sysinfo import PYPY
from .sysinfo import PYPY3
from .sysinfo import CPYTHON
from greentest.sysinfo import PLATFORM_SPECIFIC_SUFFIXES
from greentest.sysinfo import NON_APPLICABLE_SUFFIXES
from greentest.sysinfo import SHARED_OBJECT_EXTENSION
from .sysinfo import PLATFORM_SPECIFIC_SUFFIXES
from .sysinfo import NON_APPLICABLE_SUFFIXES
from .sysinfo import SHARED_OBJECT_EXTENSION
from greentest.sysinfo import RUNNING_ON_TRAVIS
from greentest.sysinfo import RUNNING_ON_APPVEYOR
from greentest.sysinfo import RUNNING_ON_CI
from .sysinfo import RUNNING_ON_TRAVIS
from .sysinfo import RUNNING_ON_APPVEYOR
from .sysinfo import RUNNING_ON_CI
from greentest.sysinfo import RESOLVER_NOT_SYSTEM
from greentest.sysinfo import RESOLVER_DNSPYTHON
from greentest.sysinfo import RESOLVER_ARES
from .sysinfo import RESOLVER_NOT_SYSTEM
from .sysinfo import RESOLVER_DNSPYTHON
from .sysinfo import RESOLVER_ARES
from greentest.sysinfo import EXPECT_POOR_TIMER_RESOLUTION
from .sysinfo import EXPECT_POOR_TIMER_RESOLUTION
from greentest.sysinfo import CONN_ABORTED_ERRORS
from .sysinfo import CONN_ABORTED_ERRORS
from greentest.skipping import skipOnWindows
from greentest.skipping import skipOnAppVeyor
from greentest.skipping import skipOnCI
from greentest.skipping import skipOnPyPy3OnCI
from greentest.skipping import skipOnPyPy
from greentest.skipping import skipOnPyPyOnCI
from greentest.skipping import skipOnPyPy3
from greentest.skipping import skipIf
from greentest.skipping import skipOnLibev
from greentest.skipping import skipOnLibuv
from greentest.skipping import skipOnLibuvOnWin
from greentest.skipping import skipOnLibuvOnCI
from greentest.skipping import skipOnLibuvOnCIOnPyPy
from greentest.skipping import skipOnLibuvOnPyPyOnWin
from greentest.skipping import skipOnPurePython
from greentest.skipping import skipWithCExtensions
from greentest.skipping import skipOnLibuvOnTravisOnCPython27
from greentest.skipping import skipOnPy37
from .skipping import skipOnWindows
from .skipping import skipOnAppVeyor
from .skipping import skipOnCI
from .skipping import skipOnPyPy3OnCI
from .skipping import skipOnPyPy
from .skipping import skipOnPyPyOnCI
from .skipping import skipOnPyPy3
from .skipping import skipIf
from .skipping import skipOnLibev
from .skipping import skipOnLibuv
from .skipping import skipOnLibuvOnWin
from .skipping import skipOnLibuvOnCI
from .skipping import skipOnLibuvOnCIOnPyPy
from .skipping import skipOnLibuvOnPyPyOnWin
from .skipping import skipOnPurePython
from .skipping import skipWithCExtensions
from .skipping import skipOnLibuvOnTravisOnCPython27
from .skipping import skipOnPy37
from greentest.exception import ExpectedException
from .exception import ExpectedException
from greentest.leakcheck import ignores_leakcheck
from .leakcheck import ignores_leakcheck
from greentest.params import LARGE_TIMEOUT
from .params import LARGE_TIMEOUT
from greentest.params import DEFAULT_LOCAL_HOST_ADDR
from greentest.params import DEFAULT_LOCAL_HOST_ADDR6
from greentest.params import DEFAULT_BIND_ADDR
from .params import DEFAULT_LOCAL_HOST_ADDR
from .params import DEFAULT_LOCAL_HOST_ADDR6
from .params import DEFAULT_BIND_ADDR
from greentest.params import DEFAULT_SOCKET_TIMEOUT
from greentest.params import DEFAULT_XPC_SOCKET_TIMEOUT
from .params import DEFAULT_SOCKET_TIMEOUT
from .params import DEFAULT_XPC_SOCKET_TIMEOUT
main = unittest.main
from greentest.hub import QuietHub
from .hub import QuietHub
import gevent.hub
gevent.hub.set_default_hub_class(QuietHub)
from greentest.sockets import bind_and_listen
from greentest.sockets import tcp_listener
from .sockets import bind_and_listen
from .sockets import tcp_listener
from greentest.openfiles import get_number_open_files
from greentest.openfiles import get_open_files
from .openfiles import get_number_open_files
from .openfiles import get_open_files
from greentest.testcase import TestCase
from .testcase import TestCase
from greentest.modules import walk_modules
from .modules import walk_modules
BaseTestCase = unittest.TestCase
from greentest.flaky import reraiseFlakyTestTimeout
from greentest.flaky import reraiseFlakyTestRaceCondition
from .flaky import reraiseFlakyTestTimeout
from .flaky import reraiseFlakyTestRaceCondition
from .flaky import reraises_flaky_timeout
from .flaky import reraises_flaky_race_condition
try:
from unittest import mock
......
......@@ -25,8 +25,8 @@ import unittest
from gevent.util import dump_stacks
from greentest import sysinfo
from greentest import six
from . import sysinfo
from . import six
class FlakyAssertionError(AssertionError):
"Re-raised so that we know it's a known-flaky test."
......@@ -96,7 +96,7 @@ if sysinfo.RUNNING_ON_CI or (sysinfo.PYPY and sysinfo.WIN):
reraiseFlakyTestTimeoutLibuv = reraiseFlakyTestTimeout
def reraises_flaky_timeout(exc_kind):
def reraises_flaky_timeout(exc_kind=AssertionError, _func=reraiseFlakyTestTimeout):
def wrapper(f):
@functools.wraps(f)
......@@ -104,7 +104,10 @@ def reraises_flaky_timeout(exc_kind):
try:
f(*args)
except exc_kind:
reraiseFlakyTestTimeout()
_func()
return m
return wrapper
def reraises_flaky_race_condition(exc_kind=AssertionError):
return reraises_flaky_timeout(exc_kind, _func=reraiseFlakyTestRaceCondition)
......@@ -22,7 +22,7 @@ from __future__ import absolute_import, print_function, division
from gevent.hub import Hub
from greentest.exception import ExpectedException
from .exception import ExpectedException
class QuietHub(Hub):
......
......@@ -68,7 +68,11 @@ class _RefCountChecker(object):
self.needs_setUp = False
def _ignore_object_p(self, obj):
if obj is self or obj in self.__dict__.values() or obj == self._ignore_object_p:
if (
obj is self
or obj in self.__dict__.values()
or obj == self._ignore_object_p # pylint:disable=comparison-with-callable
):
return False
kind = type(obj)
if kind in self.IGNORED_TYPES:
......
......@@ -19,14 +19,21 @@
# THE SOFTWARE.
from __future__ import absolute_import, print_function, division
import importlib
import os.path
import warnings
import gevent
from greentest import sysinfo
from greentest import six
from . import sysinfo
OPTIONAL_MODULES = ['resolver_ares']
OPTIONAL_MODULES = [
'gevent.resolver_ares',
'gevent.resolver.ares',
'gevent.libev',
'gevent.libev.watcher',
]
def walk_modules(basedir=None, modpath=None, include_so=False, recursive=False):
......@@ -45,6 +52,8 @@ def walk_modules(basedir=None, modpath=None, include_so=False, recursive=False):
if os.path.isdir(path):
if not recursive:
continue
if fn in ['testing', 'tests']:
continue
pkg_init = os.path.join(path, '__init__.py')
if os.path.exists(pkg_init):
yield pkg_init, modpath + fn
......@@ -58,12 +67,15 @@ def walk_modules(basedir=None, modpath=None, include_so=False, recursive=False):
if x in ['__init__', 'core', 'ares', '_util', '_semaphore',
'corecffi', '_corecffi', '_corecffi_build']:
continue
if x in OPTIONAL_MODULES:
modname = modpath + x
if modname in OPTIONAL_MODULES:
try:
six.exec_("import %s" % x, {})
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
importlib.import_module(modname)
except ImportError:
continue
yield path, modpath + x
yield path, modname
elif include_so and fn.endswith(sysinfo.SHARED_OBJECT_EXTENSION):
if '.pypy-' in fn:
continue
......
......@@ -18,9 +18,9 @@ print('Running with patch_all(%s): %s' % (','.join('%s=%r' % x for x in kwargs.i
from gevent import monkey
monkey.patch_all(**kwargs)
from greentest.sysinfo import RUNNING_ON_APPVEYOR
from greentest.sysinfo import PY37
from greentest.patched_tests_setup import disable_tests_in_source
from .sysinfo import RUNNING_ON_APPVEYOR
from .sysinfo import PY37
from .patched_tests_setup import disable_tests_in_source
try:
from test import support
except ImportError:
......
......@@ -23,7 +23,7 @@ import os
import unittest
import re
from greentest import sysinfo
from . import sysinfo
# Linux/OS X/BSD platforms can implement this by calling out to lsof
......@@ -75,11 +75,11 @@ def default_get_number_open_files():
# Linux only
fd_directory = '/proc/%d/fd' % os.getpid()
return len(os.listdir(fd_directory))
else:
try:
return len(get_open_files(pipes=True)) - 1
except (OSError, AssertionError, unittest.SkipTest):
return 0
try:
return len(get_open_files(pipes=True)) - 1
except (OSError, AssertionError, unittest.SkipTest):
return 0
lsof_get_open_files = default_get_open_files
......
......@@ -19,26 +19,26 @@
# THE SOFTWARE.
from greentest.sysinfo import PY3
from greentest.sysinfo import PYPY
from greentest.sysinfo import WIN
from greentest.sysinfo import LIBUV
from greentest.sysinfo import OSX
from .sysinfo import PY3
from .sysinfo import PYPY
from .sysinfo import WIN
from .sysinfo import LIBUV
from .sysinfo import OSX
from greentest.sysinfo import RUNNING_ON_TRAVIS
from greentest.sysinfo import RUNNING_ON_APPVEYOR
from greentest.sysinfo import EXPECT_POOR_TIMER_RESOLUTION
from greentest.sysinfo import RESOLVER_ARES
from .sysinfo import RUNNING_ON_TRAVIS
from .sysinfo import RUNNING_ON_APPVEYOR
from .sysinfo import EXPECT_POOR_TIMER_RESOLUTION
from .sysinfo import RESOLVER_ARES
# Travis is slow and overloaded; Appveyor used to be faster, but
# as of Dec 2015 it's almost always slower and/or has much worse timer
# resolution
CI_TIMEOUT = 10
CI_TIMEOUT = 15
if (PY3 and PYPY) or (PYPY and WIN and LIBUV):
# pypy3 is very slow right now,
# as is PyPy2 on windows (which only has libuv)
CI_TIMEOUT = 15
CI_TIMEOUT = 20
if PYPY and LIBUV:
# slow and flaky timeouts
LOCAL_TIMEOUT = CI_TIMEOUT
......
# pylint:disable=missing-docstring,invalid-name
# pylint:disable=missing-docstring,invalid-name,too-many-lines
from __future__ import print_function, absolute_import, division
import collections
......@@ -13,26 +13,28 @@ import os
# import platform
import re
from greentest.sysinfo import RUNNING_ON_APPVEYOR as APPVEYOR
from greentest.sysinfo import RUNNING_ON_TRAVIS as TRAVIS
from greentest.sysinfo import RESOLVER_NOT_SYSTEM as ARES
from greentest.sysinfo import RUN_COVERAGE
from .sysinfo import RUNNING_ON_APPVEYOR as APPVEYOR
from .sysinfo import RUNNING_ON_TRAVIS as TRAVIS
from .sysinfo import RESOLVER_NOT_SYSTEM as ARES
from .sysinfo import RUN_COVERAGE
from greentest.sysinfo import PYPY
from greentest.sysinfo import PYPY3
from greentest.sysinfo import PY3
from greentest.sysinfo import PY2
from greentest.sysinfo import PY34
from greentest.sysinfo import PY35
from greentest.sysinfo import PY36
from greentest.sysinfo import PY37
from .sysinfo import PYPY
from .sysinfo import PYPY3
from .sysinfo import PY3
from .sysinfo import PY2
from .sysinfo import PY34
from .sysinfo import PY35
from .sysinfo import PY36
from .sysinfo import PY37
from greentest.sysinfo import WIN
from greentest.sysinfo import OSX
from .sysinfo import WIN
from .sysinfo import OSX
from greentest.sysinfo import LIBUV
from greentest.sysinfo import CFFI_BACKEND
from .sysinfo import LIBUV
from .sysinfo import CFFI_BACKEND
from . import flaky
CPYTHON = not PYPY
......@@ -536,6 +538,14 @@ def _gc_at_end():
gc.collect()
gc.collect()
@contextlib.contextmanager
def _flaky_socket_timeout():
import socket
try:
yield
except socket.timeout:
flaky.reraiseFlakyTestTimeout()
# Map from FQN to a context manager that will be wrapped around
# that test.
wrapped_tests = {
......@@ -577,6 +587,13 @@ if WIN:
'test_ssl.ThreadedTests.test_socketserver',
]
# These are a problem on 3.5; on 3.6+ they wind up getting (accidentally) disabled.
wrapped_tests.update({
'test_socket.SendfileUsingSendTest.testWithTimeout': _flaky_socket_timeout,
'test_socket.SendfileUsingSendTest.testOffset': _flaky_socket_timeout,
'test_socket.SendfileUsingSendTest.testRegularFile': _flaky_socket_timeout,
})
if PYPY:
disabled_tests += [
# Does not exist in the CPython test suite, tests for a specific bug
......@@ -690,12 +707,7 @@ if PYPY3:
]
if PYPY and sys.pypy_version_info[:4] in ( # pylint:disable=no-member
(5, 8, 0, 'beta'), (5, 9, 0, 'beta'), (5, 10, 1, 'final')):
# 3.5 is beta. Hard to say what are real bugs in us vs real bugs in pypy.
# For that reason, we pin these patches exactly to the version in use.
if PYPY and PY3:
disabled_tests += [
# This fails to close all the FDs, at least on CI. On OS X, many of the
# POSIXProcessTestCase fd tests have issues.
......@@ -1074,7 +1086,7 @@ def disable_tests_in_source(source, filename):
# If we do it on a def-by-def basis, we can break syntax
# if the function is already decorated
pattern = r'^import .*'
replacement = r'from greentest import patched_tests_setup as _GEVENT_PTS;'
replacement = r'from gevent.testing import patched_tests_setup as _GEVENT_PTS;'
replacement += r'import unittest as _GEVENT_UTS;'
replacement += r'\g<0>'
source, n = re.subn(pattern, replacement, source, 1, re.MULTILINE)
......@@ -1085,9 +1097,10 @@ def disable_tests_in_source(source, filename):
# so use [ \t]+. Without indentation, test_main, commonly used as the
# __main__ function at the top level, could get matched. \s matches
# newlines even in MULTILINE mode so it would still match that.
my_disabled_testcases = set()
for test in my_disabled_tests:
testcase = test.split('.')[-1]
my_disabled_testcases.add(testcase)
# def foo_bar(self)
# ->
# @_GEVENT_UTS.skip('Removed by patched_tests_setup')
......@@ -1101,6 +1114,10 @@ def disable_tests_in_source(source, filename):
for test in my_wrapped_tests:
testcase = test.split('.')[-1]
if testcase in my_disabled_testcases:
print("Not wrapping %s because it is skipped" % (test,))
continue
# def foo_bar(self)
# ->
# @_GEVENT_PTS._PatchedTest('file.Case.name')
......
......@@ -21,7 +21,7 @@ from __future__ import absolute_import, print_function, division
import unittest
from greentest import sysinfo
from . import sysinfo
def _identity(f):
return f
......
......@@ -19,7 +19,7 @@
# THE SOFTWARE.
from __future__ import absolute_import, print_function, division
from greentest.params import DEFAULT_BIND_ADDR_TUPLE
from .params import DEFAULT_BIND_ADDR_TUPLE
def bind_and_listen(sock, address=DEFAULT_BIND_ADDR_TUPLE, backlog=50, reuse_addr=True):
from socket import SOL_SOCKET, SO_REUSEADDR, error
......
......@@ -23,9 +23,9 @@ from functools import wraps
from gevent.hub import _get_hub
from greentest.hub import QuietHub
from .hub import QuietHub
from greentest.patched_tests_setup import get_switch_expected
from .patched_tests_setup import get_switch_expected
def wrap_switch_count_check(method):
@wraps(method)
......
......@@ -49,9 +49,9 @@ RUN_COVERAGE = os.getenv("COVERAGE_PROCESS_START") or os.getenv("GEVENTTEST_COVE
# Generally, ignore the portions that are only implemented
# on particular platforms; they generally contain partial
# implementations completed in different modules.
PLATFORM_SPECIFIC_SUFFIXES = ['2', '279', '3']
PLATFORM_SPECIFIC_SUFFIXES = ('2', '279', '3')
if WIN:
PLATFORM_SPECIFIC_SUFFIXES.append('posix')
PLATFORM_SPECIFIC_SUFFIXES += ('posix',)
PY2 = None
PY3 = None
......@@ -60,10 +60,10 @@ PY35 = None
PY36 = None
PY37 = None
NON_APPLICABLE_SUFFIXES = []
NON_APPLICABLE_SUFFIXES = ()
if sys.version_info[0] == 3:
# Python 3
NON_APPLICABLE_SUFFIXES.extend(('2', '279'))
NON_APPLICABLE_SUFFIXES += ('2', '279')
PY2 = False
PY3 = True
if sys.version_info[1] >= 4:
......@@ -79,11 +79,11 @@ elif sys.version_info[0] == 2:
# Any python 2
PY3 = False
PY2 = True
NON_APPLICABLE_SUFFIXES.append('3')
NON_APPLICABLE_SUFFIXES += ('3',)
if (sys.version_info[1] < 7
or (sys.version_info[1] == 7 and sys.version_info[2] < 9)):
# Python 2, < 2.7.9
NON_APPLICABLE_SUFFIXES.append('279')
NON_APPLICABLE_SUFFIXES += ('279',)
PYPY3 = PYPY and PY3
......@@ -96,9 +96,9 @@ PYGTE279 = (
)
if WIN:
NON_APPLICABLE_SUFFIXES.append("posix")
NON_APPLICABLE_SUFFIXES += ("posix",)
# This is intimately tied to FileObjectPosix
NON_APPLICABLE_SUFFIXES.append("fileobject2")
NON_APPLICABLE_SUFFIXES += ("fileobject2",)
SHARED_OBJECT_EXTENSION = ".pyd"
else:
SHARED_OBJECT_EXTENSION = ".so"
......@@ -111,7 +111,7 @@ RUNNING_ON_CI = RUNNING_ON_TRAVIS or RUNNING_ON_APPVEYOR
if RUNNING_ON_APPVEYOR:
# We can't exec corecext on appveyor if we haven't run setup.py in
# 'develop' mode (i.e., we install)
NON_APPLICABLE_SUFFIXES.append('corecext')
NON_APPLICABLE_SUFFIXES += ('corecext',)
EXPECT_POOR_TIMER_RESOLUTION = (PYPY3
or RUNNING_ON_APPVEYOR
......
......@@ -20,21 +20,24 @@
from __future__ import absolute_import, print_function, division
import sys
from time import time
import os.path
from contextlib import contextmanager
from unittest import TestCase as BaseTestCase
from functools import wraps
import gevent
from greentest import sysinfo
from greentest import params
from greentest import leakcheck
from greentest import errorhandler
from greentest import flaky
from . import sysinfo
from . import params
from . import leakcheck
from . import errorhandler
from . import flaky
from greentest.patched_tests_setup import get_switch_expected
from .patched_tests_setup import get_switch_expected
class TimeAssertMixin(object):
@flaky.reraises_flaky_timeout()
def assertTimeoutAlmostEqual(self, first, second, places=None, msg=None, delta=None):
try:
self.assertAlmostEqual(first, second, places=places, msg=msg, delta=delta)
......@@ -51,6 +54,28 @@ class TimeAssertMixin(object):
self.assertLessEqual(time_taken, max_time)
self.assertGreaterEqual(time_taken, min_time)
@contextmanager
def runs_in_given_time(self, expected, fuzzy=None):
if fuzzy is None:
if sysinfo.EXPECT_POOR_TIMER_RESOLUTION or sysinfo.LIBUV:
# The noted timer jitter issues on appveyor/pypy3
fuzzy = expected * 5.0
else:
fuzzy = expected / 2.0
start = time()
yield
elapsed = time() - start
try:
self.assertTrue(
expected - fuzzy <= elapsed <= expected + fuzzy,
'Expected: %r; elapsed: %r; fuzzy %r' % (expected, elapsed, fuzzy))
except AssertionError:
flaky.reraiseFlakyTestRaceCondition()
def runs_in_no_time(
self,
fuzzy=(0.01 if not sysinfo.EXPECT_POOR_TIMER_RESOLUTION and not sysinfo.LIBUV else 1.0)):
return self.runs_in_given_time(0.0, fuzzy)
def _wrap_timeout(timeout, method):
......
......@@ -6,20 +6,19 @@ import os
import glob
import traceback
import time
import importlib
from datetime import timedelta
from multiprocessing.pool import ThreadPool
from multiprocessing import cpu_count
from greentest import util
from greentest.util import log
from greentest.sysinfo import RUNNING_ON_CI
from greentest.sysinfo import PYPY
from greentest.sysinfo import PY3
from greentest.sysinfo import PY2
from greentest.sysinfo import RESOLVER_ARES
from greentest.sysinfo import LIBUV
from greentest.sysinfo import RUN_LEAKCHECKS
from greentest import six
from . import util
from .util import log
from .sysinfo import RUNNING_ON_CI
from .sysinfo import PYPY
from .sysinfo import PY2
from .sysinfo import RESOLVER_ARES
from .sysinfo import RUN_LEAKCHECKS
from . import six
# Import this while we're probably single-threaded/single-processed
# to try to avoid issues with PyPy 5.10.
......@@ -44,76 +43,33 @@ DEFAULT_RUN_OPTIONS = {
'timeout': TIMEOUT
}
# A mapping from test file basename to a dictionary of
# options that will be applied on top of the DEFAULT_RUN_OPTIONS.
TEST_FILE_OPTIONS = {
}
if RUNNING_ON_CI:
# Too many and we get spurious timeouts
NWORKERS = 4
# tests that don't do well when run on busy box
RUN_ALONE = [
'test__threadpool.py',
'test__examples.py',
]
if RUNNING_ON_CI:
RUN_ALONE += [
# Partial workaround for the _testcapi issue on PyPy,
# but also because signal delivery can sometimes be slow, and this
# spawn processes of its own
'test_signal.py',
]
if RUN_LEAKCHECKS and PY3:
# On a heavily loaded box, these can all take upwards of 200s
RUN_ALONE += [
'test__pool.py',
'test__pywsgi.py',
'test__queue.py',
]
if PYPY:
# This often takes much longer on PyPy on CI.
TEST_FILE_OPTIONS['test__threadpool.py'] = {'timeout': 180}
if PY3:
RUN_ALONE += [
# Sometimes shows unexpected timeouts
'test_socket.py',
]
if LIBUV:
RUN_ALONE += [
# https://bitbucket.org/pypy/pypy/issues/2769/systemerror-unexpected-internal-exception
'test__pywsgi.py',
]
# tests that can't be run when coverage is enabled
IGNORE_COVERAGE = [
# Hangs forever
'test__threading_vs_settrace.py',
# times out
'test_socket.py',
# Doesn't get the exceptions it expects
'test_selectors.py',
# XXX ?
'test__issue302monkey.py',
"test_subprocess.py",
]
if PYPY:
IGNORE_COVERAGE += [
# Tends to timeout
'test__refcount.py',
'test__greenletset.py'
]
def run_many(tests, configured_failing_tests=(), failfast=False, quiet=False):
# pylint:disable=too-many-locals
def _package_relative_filename(filename, package):
if not os.path.isfile(filename) and package:
# Ok, try to locate it as a module in the package
package_dir = _dir_from_package_name(package)
return os.path.join(package_dir, filename)
return filename
def _dir_from_package_name(package):
package_mod = importlib.import_module(package)
package_dir = os.path.dirname(package_mod.__file__)
return package_dir
def run_many(tests,
configured_failing_tests=(),
failfast=False,
quiet=False,
configured_run_alone_tests=()):
# pylint:disable=too-many-locals,too-many-statements
global NWORKERS
start = time.time()
total = 0
......@@ -158,8 +114,8 @@ def run_many(tests, configured_failing_tests=(), failfast=False, quiet=False):
r = pool.apply_async(run_one, (cmd, ), options or {})
results.append(r)
return
else:
time.sleep(0.1)
time.sleep(0.05)
run_alone = []
......@@ -169,7 +125,7 @@ def run_many(tests, configured_failing_tests=(), failfast=False, quiet=False):
for cmd, options in tests:
total += 1
options = options or {}
if matches(RUN_ALONE, cmd):
if matches(configured_run_alone_tests, cmd):
run_alone.append((cmd, options))
else:
spawn(cmd, options)
......@@ -199,17 +155,30 @@ def run_many(tests, configured_failing_tests=(), failfast=False, quiet=False):
report(total, failed, passed, took=time.time() - start,
configured_failing_tests=configured_failing_tests)
def discover(tests=None, ignore_files=None,
ignored=(), coverage=False):
def discover(
tests=None, ignore_files=None,
ignored=(), coverage=False,
package=None,
configured_ignore_coverage=(),
configured_test_options=None,
):
# pylint:disable=too-many-locals,too-many-branches
configured_test_options = configured_test_options or {}
olddir = os.getcwd()
ignore = set(ignored or ())
if ignore_files:
ignore_files = ignore_files.split(',')
for f in ignore_files:
ignore.update(set(load_list_from_file(f)))
ignore.update(set(load_list_from_file(f, package)))
if coverage:
ignore.update(IGNORE_COVERAGE)
ignore.update(configured_ignore_coverage)
if package:
package_dir = _dir_from_package_name(package)
# We need to glob relative names, our config is based on filenames still
os.chdir(package_dir)
if not tests:
tests = set(glob.glob('test_*.py')) - set(['test_support.py'])
......@@ -228,14 +197,20 @@ def discover(tests=None, ignore_files=None,
for filename in tests:
with open(filename, 'rb') as f:
module_name = os.path.splitext(filename)[0]
qualified_name = package + '.' + module_name if package else module_name
with open(os.path.abspath(filename), 'rb') as f:
# Some of the test files (e.g., test__socket_dns) are
# UTF8 encoded. Depending on the environment, Python 3 may
# try to decode those as ASCII, which fails with UnicodeDecodeError.
# Thus, be sure to open and compare in binary mode.
# Open the absolute path to make errors more clear,
# but we can't store the absolute path, our configuration is based on
# relative file names.
contents = f.read()
if b'TESTRUNNER' in contents: # test__monkey_patching.py
module = __import__(filename.rsplit('.', 1)[0])
# XXX: Rework this to avoid importing.
module = importlib.import_module(qualified_name)
for cmd, options in module.TESTRUNNER():
if remove_options(cmd)[-1] in ignore:
continue
......@@ -245,25 +220,32 @@ def discover(tests=None, ignore_files=None,
if PYPY and PY2:
# Doesn't seem to be an env var for this
cmd.extend(('-X', 'track-resources'))
cmd.append(filename)
if package:
# Using a package is the best way to work with coverage 5
# when we specify 'source = <package>'
cmd.append('-m' + qualified_name)
else:
cmd.append(filename)
options = DEFAULT_RUN_OPTIONS.copy()
options.update(TEST_FILE_OPTIONS.get(filename, {}))
options.update(configured_test_options.get(filename, {}))
to_process.append((cmd, options))
os.chdir(olddir)
return to_process
def remove_options(lst):
return [x for x in lst if x and not x.startswith('-')]
def load_list_from_file(filename):
def load_list_from_file(filename, package):
result = []
if filename:
for x in open(filename):
x = x.split('#', 1)[0].strip()
if x:
result.append(x)
with open(_package_relative_filename(filename, package)) as f:
for x in f:
x = x.split('#', 1)[0].strip()
if x:
result.append(x)
return result
......@@ -273,7 +255,12 @@ def matches(possibilities, command, include_flaky=True):
for line in possibilities:
if not include_flaky and line.startswith('FLAKY '):
continue
if command.endswith(' ' + line.replace('FLAKY ', '')):
line = line.replace('FLAKY ', '')
# Our configs are still mostly written in terms of file names,
# but the non-monkey tests are now using package names.
# Strip off '.py' from filenames to see if we match a module.
# XXX: This could be much better. Our command needs better structure.
if command.endswith(' ' + line) or command.endswith(line.replace(".py", '')):
return True
return False
......@@ -387,14 +374,10 @@ def _setup_environ(debug=False):
# Python 3.6
os.environ['PYTHONMALLOC'] = 'debug'
if (sys.version_info == (3, 7, 0, 'beta', 2)
and (os.environ.get("PYTHONDEVMODE") or os.environ.get('PYTHONMALLOC'))):
# See https://twitter.com/ossmkitty/status/970693025130311680
# https://bugs.python.org/issue33005
os.environ.pop('PYTHONDEVMODE', None)
os.environ.pop('PYTHONMALLOC', None)
def main():
# pylint:disable=too-many-locals,too-many-statements
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--ignore')
......@@ -406,40 +389,54 @@ def main():
parser.add_argument("--quiet", action="store_true", default=True)
parser.add_argument("--verbose", action="store_false", dest='quiet')
parser.add_argument("--debug", action="store_true", default=False)
parser.add_argument("--package", default="gevent.tests")
parser.add_argument('tests', nargs='*')
options = parser.parse_args()
FAILING_TESTS = []
IGNORED_TESTS = []
RUN_ALONE = []
TEST_FILE_OPTIONS = {}
coverage = False
if options.coverage or os.environ.get("GEVENTTEST_COVERAGE"):
coverage = True
# NOTE: This must be run from the greentest directory
os.environ['COVERAGE_PROCESS_START'] = os.path.abspath(".coveragerc")
if PYPY:
os.environ['COVERAGE_PROCESS_START'] = os.path.abspath(".coveragerc-pypy")
os.environ['PYTHONPATH'] = os.path.abspath("coveragesite") + os.pathsep + os.environ.get("PYTHONPATH", "")
this_dir = os.path.dirname(__file__)
site_dir = os.path.join(this_dir, 'coveragesite')
site_dir = os.path.abspath(site_dir)
os.environ['PYTHONPATH'] = site_dir + os.pathsep + os.environ.get("PYTHONPATH", "")
# We change directory often, use an absolute path to keep all the
# coverage files (which will have distinct suffixes because of parallel=true in .coveragerc
# in this directory; makes them easier to combine and use with coverage report)
os.environ['COVERAGE_FILE'] = os.path.abspath(".") + os.sep + ".coverage"
print("Enabling coverage to", os.environ['COVERAGE_FILE'])
print("Enabling coverage to", os.environ['COVERAGE_FILE'], "with site", site_dir)
_setup_environ(debug=options.debug)
if options.config:
config = {}
options.config = _package_relative_filename(options.config, options.package)
with open(options.config) as f:
config_data = f.read()
six.exec_(config_data, config)
FAILING_TESTS = config['FAILING_TESTS']
IGNORED_TESTS = config['IGNORED_TESTS']
tests = discover(options.tests,
ignore_files=options.ignore,
ignored=IGNORED_TESTS,
coverage=coverage)
RUN_ALONE = config['RUN_ALONE']
TEST_FILE_OPTIONS = config['TEST_FILE_OPTIONS']
IGNORE_COVERAGE = config['IGNORE_COVERAGE']
tests = discover(
options.tests,
ignore_files=options.ignore,
ignored=IGNORED_TESTS,
coverage=coverage,
package=options.package,
configured_ignore_coverage=IGNORE_COVERAGE,
configured_test_options=TEST_FILE_OPTIONS,
)
if options.discover:
for cmd, options in tests:
print(util.getname(cmd, env=options.get('env'), setenv=options.get('setenv')))
......@@ -449,7 +446,17 @@ def main():
# XXX: Add a way to force these.
print("Not running tests on pypy with c-ares; not a supported configuration")
return
run_many(tests, configured_failing_tests=FAILING_TESTS, failfast=options.failfast, quiet=options.quiet)
if options.package:
# Put this directory on the path so relative imports work.
package_dir = _dir_from_package_name(options.package)
os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', "") + os.pathsep + package_dir
run_many(
tests,
configured_failing_tests=FAILING_TESTS,
failfast=options.failfast,
quiet=options.quiet,
configured_run_alone_tests=RUN_ALONE,
)
if __name__ == '__main__':
......
......@@ -22,9 +22,9 @@ import time
import gevent
from greentest import sysinfo
from greentest import leakcheck
from greentest.testcase import TestCase
from . import sysinfo
from . import leakcheck
from .testcase import TestCase
SMALLEST_RELIABLE_DELAY = 0.001 # 1ms, because of libuv
......
import sys
import os
from greentest import six
from . import six
import traceback
import unittest
import threading
......@@ -298,8 +298,18 @@ def run(command, **kwargs):
return RunResult(result, out, name)
def find_setup_py_above(a_file):
"Return the directory containing setup.py somewhere above *a_file*"
root = os.path.dirname(os.path.abspath(a_file))
while not os.path.exists(os.path.join(root, 'setup.py')):
prev, root = root, os.path.dirname(root)
if root == prev:
# Let's avoid infinite loops at root
raise AssertionError('could not find my setup.py')
return root
class TestServer(unittest.TestCase):
cwd = '../../examples/'
args = []
before_delay = 3
after_delay = 0.5
......@@ -307,6 +317,19 @@ class TestServer(unittest.TestCase):
server = None # subclasses define this to be the path to the server.py
start_kwargs = None
def find_setup_py(self):
"Return the directory containing setup.py"
return find_setup_py_above(__file__)
# XXX: We need to extend this if we want it to be useful
# for other packages; our __file__ won't work for them.
# We can look at the CWD, and we can look at the __file__ of the
# sys.modules[type(self).__module__].
@property
def cwd(self):
root = self.find_setup_py()
return os.path.join(root, 'examples')
def start(self):
kwargs = self.start_kwargs or {}
return start([sys.executable, '-u', self.server] + self.args, cwd=self.cwd, **kwargs)
......
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANtb0+YrKuxevGpm
LrjaUhZSgz6zFAmuGFmKmUbdjmfv9zSmmdsQIksK++jK0Be9LeZy20j6ahOfuVa0
ufEmPoP7Fy4hXegKZR9cCWcIe/A6H2xWF1IIJLRTLaU8ol/I7T+um5HD5AwAwNPP
USNU0Eegmvp+xxWu3NX2m1Veot85AgMBAAECgYA3ZdZ673X0oexFlq7AAmrutkHt
CL7LvwrpOiaBjhyTxTeSNWzvtQBkIU8DOI0bIazA4UreAFffwtvEuPmonDb3F+Iq
SMAu42XcGyVZEl+gHlTPU9XRX7nTOXVt+MlRRRxL6t9GkGfUAXI3XxJDXW3c0vBK
UL9xqD8cORXOfE06rQJBAP8mEX1ERkR64Ptsoe4281vjTlNfIbs7NMPkUnrn9N/Y
BLhjNIfQ3HFZG8BTMLfX7kCS9D593DW5tV4Z9BP/c6cCQQDcFzCcVArNh2JSywOQ
ZfTfRbJg/Z5Lt9Fkngv1meeGNPgIMLN8Sg679pAOOWmzdMO3V706rNPzSVMME7E5
oPIfAkEA8pDddarP5tCvTTgUpmTFbakm0KoTZm2+FzHcnA4jRh+XNTjTOv98Y6Ik
eO5d1ZnKXseWvkZncQgxfdnMqqpj5wJAcNq/RVne1DbYlwWchT2Si65MYmmJ8t+F
0mcsULqjOnEMwf5e+ptq5LzwbyrHZYq5FNk7ocufPv/ZQrcSSC+cFwJBAKvOJByS
x56qyGeZLOQlWS2JS3KJo59XuLFGqcbgN9Om9xFa41Yb4N9NvplFivsvZdw3m1Q/
SPIXQuT8RMPDVNQ=
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICVDCCAb2gAwIBAgIJANfHOBkZr8JOMA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV
BAYTAlhZMRcwFQYDVQQHEw5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9u
IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMDEw
MDgyMzAxNTZaFw0yMDEwMDUyMzAxNTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH
Ew5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9uIFNvZnR3YXJlIEZvdW5k
YXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEA21vT5isq7F68amYuuNpSFlKDPrMUCa4YWYqZRt2OZ+/3NKaZ2xAiSwr7
6MrQF70t5nLbSPpqE5+5VrS58SY+g/sXLiFd6AplH1wJZwh78DofbFYXUggktFMt
pTyiX8jtP66bkcPkDADA089RI1TQR6Ca+n7HFa7c1fabVV6i3zkCAwEAAaMYMBYw
FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAHPctQBEQ4wd
BJ6+JcpIraopLn8BGhbjNWj40mmRqWB/NAWF6M5ne7KpGAu7tLeG4hb1zLaldK8G
lxy2GPSRF6LFS48dpEj2HbMv2nvv6xxalDMJ9+DicWgAKTQ6bcX2j3GUkCR0g/T1
CRlNBAAlvhKzO7Clpf9l0YKBEfraJByX
-----END CERTIFICATE-----
......@@ -2,5 +2,5 @@
from __future__ import print_function, absolute_import, division
if __name__ == '__main__':
from greentest import testrunner
from gevent.testing import testrunner
testrunner.main()
......@@ -6,17 +6,17 @@ import os
import sys
import struct
from greentest.sysinfo import RUNNING_ON_APPVEYOR as APPVEYOR
from greentest.sysinfo import RUNNING_ON_TRAVIS as TRAVIS
from greentest.sysinfo import RUN_LEAKCHECKS as LEAKTEST
from greentest.sysinfo import RUN_COVERAGE as COVERAGE
from greentest.sysinfo import RESOLVER_NOT_SYSTEM
from gevent.testing.sysinfo import RUNNING_ON_APPVEYOR as APPVEYOR
from gevent.testing.sysinfo import RUNNING_ON_TRAVIS as TRAVIS
from gevent.testing.sysinfo import RUN_LEAKCHECKS as LEAKTEST
from gevent.testing.sysinfo import RUN_COVERAGE as COVERAGE
from gevent.testing.sysinfo import RESOLVER_NOT_SYSTEM
from greentest.sysinfo import PYPY
from greentest.sysinfo import PY3
from greentest.sysinfo import PY35
from gevent.testing.sysinfo import PYPY
from gevent.testing.sysinfo import PY3
from gevent.testing.sysinfo import PY35
from greentest.sysinfo import LIBUV
from gevent.testing.sysinfo import LIBUV
IGNORED_TESTS = []
......@@ -85,6 +85,32 @@ if sys.platform == 'win32':
# too tight for appveyor. This happens even if Event isn't
# monkey-patched
'FLAKY test_threading.py',
# Starting in November 2018, on Python 3.7.0, we observe this test crashing.
# I can't reproduce locally.
# | C:\Python37-x64\python.exe -u -mgevent.tests.test__greenness
# 127.0.0.1 - - [09/Nov/2018 16:34:12] code 501, message Unsupported method ('GET')
# 127.0.0.1 - - [09/Nov/2018 16:34:12] "GET / HTTP/1.1" 501 -
# .
# ----------------------------------------------------------------------
# Ran 1 test in 0.031s
# OK
# Windows fatal exception: access violation
# Current thread 0x000003c8 (most recent call first):
# File "c:\projects\gevent\src\gevent\threadpool.py", line 261 in _worker
# Thread 0x00000600 (most recent call first):
# File "c:\projects\gevent\src\gevent\libuv\watcher.py", line 577 in send
# File "c:\projects\gevent\src\gevent\threadpool.py", line 408 in set
# File "c:\projects\gevent\src\gevent\threadpool.py", line 290 in _worker
# Thread 0x000007d4 (most recent call first):
# File "C:\Python37-x64\lib\weakref.py", line 356 in remove
# ! C:\Python37-x64\python.exe -u -mgevent.tests.test__greenness [code 3221225477] [took 1.3s]
'FLAKY test__greenness.py',
]
if not PY35:
......@@ -189,7 +215,7 @@ if PYPY:
# This test, which normally takes 4-5s, sometimes
# hangs forever after running two tests. I cannot reproduce,
# it seems highly load dependent. Observed with both libev and libuv.
'test_threading_2.py',
'test__threading_2.py',
]
if PY3 and TRAVIS:
......@@ -236,5 +262,71 @@ if COVERAGE:
FAILING_TESTS = [x.strip() for x in set(FAILING_TESTS) if x.strip()]
# A mapping from test file basename to a dictionary of
# options that will be applied on top of the DEFAULT_RUN_OPTIONS.
TEST_FILE_OPTIONS = {
}
# tests that don't do well when run on busy box
RUN_ALONE = [
'test__threadpool.py',
'test__examples.py',
]
if APPVEYOR or TRAVIS:
RUN_ALONE += [
# Partial workaround for the _testcapi issue on PyPy,
# but also because signal delivery can sometimes be slow, and this
# spawn processes of its own
'test_signal.py',
]
if LEAKTEST and PY3:
# On a heavily loaded box, these can all take upwards of 200s
RUN_ALONE += [
'test__pool.py',
'test__pywsgi.py',
'test__queue.py',
]
if PYPY:
# This often takes much longer on PyPy on CI.
TEST_FILE_OPTIONS['test__threadpool.py'] = {'timeout': 180}
TEST_FILE_OPTIONS['test__threading_2.py'] = {'timeout': 180}
if PY3:
RUN_ALONE += [
# Sometimes shows unexpected timeouts
'test_socket.py',
]
if LIBUV:
RUN_ALONE += [
# https://bitbucket.org/pypy/pypy/issues/2769/systemerror-unexpected-internal-exception
'test__pywsgi.py',
]
# tests that can't be run when coverage is enabled
IGNORE_COVERAGE = [
# Hangs forever
'test__threading_vs_settrace.py',
# times out
'test_socket.py',
# Doesn't get the exceptions it expects
'test_selectors.py',
# XXX ?
'test__issue302monkey.py',
"test_subprocess.py",
]
if PYPY:
IGNORE_COVERAGE += [
# Tends to timeout
'test__refcount.py',
'test__greenletset.py'
]
if __name__ == '__main__':
print('known_failures:\n', FAILING_TESTS)
"""
Various tests for synchronization primitives.
"""
# pylint:disable=no-member,abstract-method
import sys
import time
try:
......@@ -15,7 +16,7 @@ try:
except ImportError:
from test import test_support as support
from greentest.testcase import TimeAssertMixin
from gevent.testing.testcase import TimeAssertMixin
def _wait():
# A crude wait/yield function not relying on synchronization primitives.
......@@ -131,7 +132,7 @@ class BaseLockTests(BaseTestCase):
def _with(err=None):
with lock:
if err is not None:
raise err
raise err # pylint:disable=raising-bad-type
_with()
# Check the lock is unacquired
Bunch(f, 1).wait_for_finished()
......@@ -153,7 +154,7 @@ class BaseLockTests(BaseTestCase):
self.assertEqual(n, len(threading.enumerate()))
class LockTests(BaseLockTests):
class LockTests(BaseLockTests): # pylint:disable=abstract-method
"""
Tests for non-recursive, weak locks
(which can be acquired and released from different threads).
......@@ -168,7 +169,7 @@ class LockTests(BaseLockTests):
lock.acquire()
phase.append(None)
start_new_thread(f, ())
while len(phase) == 0:
while not phase:
_wait()
_wait()
self.assertEqual(len(phase), 1)
......@@ -436,9 +437,10 @@ class BaseSemaphoreTests(BaseTestCase):
raise NotImplementedError()
def test_constructor(self):
self.assertRaises(ValueError, self.semtype, value = -1)
self.assertRaises(ValueError, self.semtype, value=-1)
# Py3 doesn't have sys.maxint
self.assertRaises(ValueError, self.semtype, value = -getattr(sys, 'maxint', getattr(sys, 'maxsize', None)))
self.assertRaises(ValueError, self.semtype,
value=-getattr(sys, 'maxint', getattr(sys, 'maxsize', None)))
def test_acquire(self):
sem = self.semtype(1)
......@@ -509,7 +511,7 @@ class BaseSemaphoreTests(BaseTestCase):
# There can be a thread switch between acquiring the semaphore and
# appending the result, therefore results will not necessarily be
# ordered.
self.assertEqual(sorted(results), [False] * 7 + [True] * 3 )
self.assertEqual(sorted(results), [False] * 7 + [True] * 3)
def test_default_value(self):
# The default initial value is 1.
......@@ -534,7 +536,7 @@ class BaseSemaphoreTests(BaseTestCase):
with sem:
self.assertFalse(sem.acquire(False))
if err:
raise err
raise err # pylint:disable=raising-bad-type
_with()
self.assertTrue(sem.acquire(False))
sem.release()
......@@ -603,7 +605,7 @@ class BarrierTests(BaseTestCase):
"""
Test that a barrier is passed in lockstep
"""
results = [[],[]]
results = [[], []]
def f():
self.multipass(results, passes)
self.run_threads(f)
......@@ -657,7 +659,6 @@ class BarrierTests(BaseTestCase):
results2.append(True)
except RuntimeError:
self.barrier.abort()
pass
self.run_threads(f)
self.assertEqual(len(results1), 0)
......@@ -713,7 +714,7 @@ class BarrierTests(BaseTestCase):
results2.append(True)
except RuntimeError:
self.barrier.abort()
pass
# Synchronize and reset the barrier. Must synchronize first so
# that everyone has left it when we reset, and after so that no
# one enters it before the reset.
......
......@@ -9,10 +9,10 @@ from unittest import SkipTest
import socket
import ssl
import greentest
from greentest import DEFAULT_XPC_SOCKET_TIMEOUT
from greentest import util
from greentest import params
import gevent.testing as greentest
from gevent.testing import DEFAULT_XPC_SOCKET_TIMEOUT
from gevent.testing import util
from gevent.testing import params
@greentest.skipOnCI("Timing issues sometimes lead to a connection refused")
class Test_wsgiserver(util.TestServer):
......
......@@ -8,7 +8,7 @@ from __future__ import print_function
import gc
import greentest
import gevent.testing as greentest
from gevent._ident import IdentRegistry
from gevent._compat import PYPY
......
......@@ -11,7 +11,7 @@ from gevent.monkey import get_original
from gevent._compat import thread_mod_name
from gevent._compat import NativeStrIO
from greentest.skipping import skipOnPyPyOnWindows
from gevent.testing.skipping import skipOnPyPyOnWindows
from gevent import _monitor as monitor
from gevent import config as GEVENT_CONFIG
......
......@@ -5,7 +5,11 @@ import glob
import atexit
# subprocess: include in subprocess tests
from greentest import util
from gevent.testing import util
# XXX: Generalize this so other packages can use it.
setup_py = util.find_setup_py_above(__file__)
greentest = os.path.join(setup_py, 'src', 'greentest')
TIMEOUT = 120
directory = '%s.%s' % sys.version_info[:2]
......@@ -13,6 +17,10 @@ full_directory = '%s.%s.%s' % sys.version_info[:3]
if hasattr(sys, 'pypy_version_info'):
directory += 'pypy'
full_directory += 'pypy'
directory = os.path.join(greentest, directory)
full_directory = os.path.join(greentest, full_directory)
version = '%s.%s.%s' % sys.version_info[:3]
if sys.version_info[3] == 'alpha':
version += 'a%s' % sys.version_info[4]
......@@ -62,7 +70,7 @@ def TESTRUNNER(tests=None):
if tests and not sys.platform.startswith("win"):
atexit.register(os.system, 'rm -f */@test*')
basic_args = [sys.executable, '-u', '-W', 'ignore', '-m' 'greentest.monkey_test']
basic_args = [sys.executable, '-u', '-W', 'ignore', '-m' 'gevent.testing.monkey_test']
for filename in tests:
if filename in version_tests:
util.log("Overriding %s from %s with file from %s", filename, directory, full_directory)
......@@ -75,7 +83,7 @@ def TESTRUNNER(tests=None):
def main():
from greentest import testrunner
from gevent.testing import testrunner
return testrunner.run_many(list(TESTRUNNER(sys.argv[1:])))
......
"""Check __all__, __implements__, __extensions__, __imports__ of the modules"""
from __future__ import print_function
from greentest import six
import sys
import unittest
import types
from greentest.modules import walk_modules
from greentest.sysinfo import PLATFORM_SPECIFIC_SUFFIXES
import importlib
import warnings
from gevent.testing import six
from gevent.testing.modules import walk_modules
from gevent.testing.sysinfo import PLATFORM_SPECIFIC_SUFFIXES
from gevent._patcher import MAPPING
......@@ -30,7 +34,9 @@ COULD_BE_MISSING = {
'subprocess': ['_posixsubprocess'],
}
NO_ALL = [
# Things without an __all__ should generally be internal implementation
# helpers
NO_ALL = {
'gevent.threading',
'gevent._util',
'gevent._compat',
......@@ -40,7 +46,8 @@ NO_ALL = [
'gevent._tblib',
'gevent._corecffi',
'gevent._patcher',
]
'gevent._ffi',
}
ALLOW_IMPLEMENTS = [
'gevent._queue',
......@@ -133,7 +140,7 @@ class Test(unittest.TestCase):
if hasattr(self.stdlib_module, name):
raise AssertionError("'%r' is not an extension, it is found in %r" % (name, self.stdlib_module))
def check_completeness(self):
def check_completeness(self): # pylint:disable=too-many-branches
"""Check that __all__ (or dir()) of the corresponsing stdlib is a subset of __all__ of this module"""
missed = []
for name in self.stdlib_all:
......@@ -175,13 +182,13 @@ are missing from %r:
raise AssertionError(msg)
def _test(self, modname):
for x in PLATFORM_SPECIFIC_SUFFIXES:
if modname.endswith(x):
return
if modname.endswith(PLATFORM_SPECIFIC_SUFFIXES):
return
self.modname = modname
six.exec_("import %s" % modname, {})
self.module = sys.modules[modname]
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
self.module = importlib.import_module(modname)
self.check_all()
......@@ -216,14 +223,17 @@ are missing from %r:
path = modname = orig_modname = None
for path, modname in walk_modules(include_so=True):
for path, modname in walk_modules(include_so=False, recursive=True):
orig_modname = modname
modname = modname.replace('gevent.', '').split('.')[0]
if not modname:
print("WARNING: No such module '%s' at '%s'" % (orig_modname, path),
file=sys.stderr)
continue
exec('''def test_%s(self): self._test("gevent.%s")''' % (modname, modname))
exec(
'''def test_%s(self): self._test("%s")''' % (
orig_modname.replace('.', '_').replace('-', '_'), orig_modname)
)
del path, modname, orig_modname
......
......@@ -19,7 +19,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import greentest
import gevent.testing as greentest
import gevent
from gevent import util, socket
......@@ -36,10 +36,10 @@ class Test(greentest.TestCase):
try:
state.append('start')
gevent.sleep(DELAY * 3.0)
except:
except: # pylint:disable=bare-except
state.append('except')
# catching GreenletExit
pass
state.append('finished')
g = gevent.spawn(test)
......@@ -68,7 +68,9 @@ class Test(greentest.TestCase):
def _test_wait_read_invalid_switch(self, sleep):
sock1, sock2 = socket.socketpair()
try:
p = gevent.spawn(util.wrap_errors(AssertionError, socket.wait_read), sock1.fileno())
p = gevent.spawn(util.wrap_errors(AssertionError,
socket.wait_read), # pylint:disable=no-member
sock1.fileno())
gevent.get_hub().loop.run_callback(switch_None, p)
if sleep is not None:
gevent.sleep(sleep)
......
......@@ -20,7 +20,7 @@
# THE SOFTWARE.
import sys
import greentest
import gevent.testing as greentest
import weakref
import time
import gc
......@@ -30,7 +30,8 @@ from gevent import Timeout
from gevent import get_hub
from greentest.timing import SMALL_TICK as DELAY
from gevent.testing.timing import SMALL_TICK as DELAY
from gevent.testing import flaky
class Error(Exception):
......@@ -106,6 +107,8 @@ class Test(greentest.TestCase):
@greentest.skipOnAppVeyor("Timing is flaky, especially under Py 3.4/64-bit")
@greentest.skipOnPyPy3OnCI("Timing is flaky, especially under Py 3.4/64-bit")
@greentest.reraises_flaky_timeout(Timeout)
def test_api(self):
# Nothing happens if with-block finishes before the timeout expires
t = Timeout(DELAY * 2)
......@@ -173,7 +176,7 @@ class Test(greentest.TestCase):
gc.collect()
self.assertFalse(err_ref(), err_ref)
@flaky.reraises_flaky_race_condition()
def test_nested_timeout(self):
with Timeout(DELAY, False):
with Timeout(DELAY * 10, False):
......
......@@ -2,7 +2,7 @@ from __future__ import print_function
import pickle
import sys
import greentest
import gevent.testing as greentest
try:
from gevent.resolver.cares import ares_host_result
except ImportError as ex:
......
from __future__ import print_function
import errno
import unittest
import gevent
try:
from gevent.resolver.ares import Resolver
except ImportError as ex:
Resolver = None
from gevent import socket
import gevent.testing as greentest
@unittest.skipIf(
Resolver is None,
"Needs ares resolver"
)
class TestTimeout(greentest.TestCase):
__timeout__ = 30
address = ('', 7153)
def test(self):
listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
listener.bind(self.address)
except socket.error as ex:
if ex.errno in (errno.EPERM, errno.EADDRNOTAVAIL) or 'permission denied' in str(ex).lower():
raise unittest.SkipTest(
'This test binds on port a port that was already in use or not allowed.\n'
)
raise
def reader():
while True:
listener.recvfrom(10000)
gevent.spawn(reader)
r = Resolver(servers=['127.0.0.1'], timeout=0.001, tries=1,
udp_port=self.address[-1])
with self.assertRaisesRegex(socket.gaierror, "ARES_ETIMEOUT"):
r.gethostbyname('www.google.com')
if __name__ == '__main__':
greentest.main()
from __future__ import print_function
import greentest
import gevent.testing as greentest
import gevent
from gevent import socket
from gevent import backdoor
......
from __future__ import print_function
import os
import unittest
import gevent
from gevent import core
@unittest.skipUnless(
getattr(core, 'LIBEV_EMBED', False),
"Needs embedded libev. "
"hub.loop.fileno is only defined when "
"we embed libev for some reason. "
"Choosing specific backends is also only supported by libev "
"(not libuv), and besides, libuv has a nasty tendency to "
"abort() the process if its FD gets closed. "
)
class Test(unittest.TestCase):
# NOTE that we extend unittest.TestCase, not greentest.TestCase
# Extending the later causes the wrong hub to get used.
assertRaisesRegex = getattr(unittest.TestCase, 'assertRaisesRegex',
getattr(unittest.TestCase, 'assertRaisesRegexp'))
def _check_backend(self, backend):
hub = gevent.get_hub(backend, default=False)
try:
self.assertEqual(hub.loop.backend, backend)
gevent.sleep(0.001)
fileno = hub.loop.fileno()
if fileno is None:
raise unittest.SkipTest("backend %s lacks fileno" % (backend,))
os.close(fileno)
with self.assertRaisesRegex(SystemError, "(libev)"):
gevent.sleep(0.001)
hub.destroy()
self.assertIn('destroyed', repr(hub))
finally:
if hub.loop is not None:
hub.destroy()
def _make_test(count, backend): # pylint:disable=no-self-argument
def test(self):
self._check_backend(backend)
test.__name__ = 'test_' + backend + '_' + str(count)
return test.__name__, test
count = backend = None
for count in range(2):
for backend in core.supported_backends():
name, func = _make_test(count, backend)
locals()[name] = func
name = func = None
del count
del backend
del _make_test
if __name__ == '__main__':
unittest.main()
......@@ -2,7 +2,7 @@
from __future__ import absolute_import, print_function, division
import sys
import unittest
import greentest
import gevent.testing as greentest
from gevent import core
......
from __future__ import print_function
import gevent.monkey; gevent.monkey.patch_all()
import gevent.monkey
gevent.monkey.patch_all()
import gevent
import os
......
......@@ -6,11 +6,11 @@ import test__core_loop_run # this runs main tests, fails if signal() is not call
assert test__core_loop_run # pyflakes
from gevent.hub import signal as hub_signal
from gevent import signal
from gevent import signal as top_signal # pylint:disable=reimported
assert gevent.signal is hub_signal
assert gevent.signal is signal
assert gevent.signal is top_signal
assert hasattr(gevent.signal, 'signal')
s = signal(2, sys.stderr.write, 'INTERRUPT')
assert isinstance(s, signal)
s = top_signal(2, sys.stderr.write, 'INTERRUPT')
assert isinstance(s, top_signal)
assert isinstance(s, hub_signal)
......@@ -7,8 +7,8 @@ import time
import gevent
import gevent.core
import greentest
import greentest.flaky
import gevent.testing as greentest
import gevent.testing.flaky
#pylint: disable=protected-access
......@@ -83,7 +83,7 @@ class TestCoreStat(greentest.TestCase):
if reaction <= 0.0:
# Sigh. This is especially true on PyPy on Windows
raise greentest.flaky.FlakyTestRaceCondition(
raise gevent.testing.flaky.FlakyTestRaceCondition(
"Bad timer resolution (on Windows?), test is useless. Start %s, now %s" % (start, now))
self.assertGreaterEqual(
......
from __future__ import print_function
from gevent import config
import greentest
from greentest import TestCase
from greentest import LARGE_TIMEOUT
from greentest.sysinfo import CFFI_BACKEND
from greentest.flaky import reraises_flaky_timeout
import gevent.testing as greentest
from gevent.testing import TestCase
from gevent.testing import LARGE_TIMEOUT
from gevent.testing.sysinfo import CFFI_BACKEND
from gevent.testing.flaky import reraises_flaky_timeout
class Test(TestCase):
......@@ -94,7 +94,7 @@ class TestTimerResolution(Test):
# On CI, with *all* backends, sometimes we get timer values of
# 0.02 or higher.
@reraises_flaky_timeout(AssertionError)
def test_resolution(self):
def test_resolution(self): # pylint:disable=too-many-locals
# Make sure that having an active IO watcher
# doesn't badly throw off our timer resolution.
# (This was a specific problem with libuv)
......
from __future__ import absolute_import, print_function
import greentest
import gevent.testing as greentest
from gevent import config
from greentest.sysinfo import CFFI_BACKEND
from gevent.testing.sysinfo import CFFI_BACKEND
from gevent.core import READ # pylint:disable=no-name-in-module
from gevent.core import WRITE # pylint:disable=no-name-in-module
......
from __future__ import print_function
import doctest
import functools
import os
import re
import sys
import traceback
import unittest
import gevent
from gevent import socket
from greentest import walk_modules
from greentest import sysinfo
from gevent.testing import walk_modules
from gevent.testing import sysinfo
from gevent.testing import util
# Ignore tracebacks: ZeroDivisionError
def myfunction(*args, **kwargs):
def myfunction(*_args, **_kwargs):
pass
......@@ -44,29 +45,44 @@ if sysinfo.WIN:
'gevent.subprocess',
}
if __name__ == '__main__':
class Modules(object):
def __init__(self, allowed_modules):
self.allowed_modules = allowed_modules
self.modules = set()
for path, module in walk_modules():
self.add_module(module, path)
def add_module(self, name, path):
if self.allowed_modules and name not in self.allowed_modules:
return
if name in FORBIDDEN_MODULES:
return
self.modules.add((name, path))
def __bool__(self):
return bool(self.modules)
__nonzero__ = __bool__
def __iter__(self):
return iter(self.modules)
def main():
cwd = os.getcwd()
try:
allowed_modules = sys.argv[1:]
sys.path.append('.')
base = os.path.dirname(gevent.__file__)
print(base)
os.chdir('../..')
os.chdir(util.find_setup_py_above(__file__))
globs = {'myfunction': myfunction, 'gevent': gevent, 'socket': socket}
modules = set()
modules = Modules(allowed_modules)
def add_module(name, path):
if allowed_modules and name not in allowed_modules:
return
if name in FORBIDDEN_MODULES:
return
modules.add((name, path))
for path, module in walk_modules():
add_module(module, path)
add_module('setup', 'setup.py')
modules.add_module('setup', 'setup.py')
if not modules:
sys.exit('No modules found matching %s' % ' '.join(allowed_modules))
......@@ -88,18 +104,18 @@ if __name__ == '__main__':
with open(path, 'rb') as f:
contents = f.read()
if re.search(br'^\s*>>> ', contents, re.M):
try:
s = doctest.DocTestSuite(m, extraglobs=globs, checker=checker)
test_count = len(s._tests) # pylint: disable=W0212
print('%s (from %s): %s tests' % (m, path, test_count))
suite.addTest(s)
modules_count += 1
tests_count += test_count
except Exception:
traceback.print_exc()
sys.stderr.write('Failed to process %s\n\n' % path)
s = doctest.DocTestSuite(m, extraglobs=globs, checker=checker)
test_count = len(s._tests)
print('%s (from %s): %s tests' % (m, path, test_count))
suite.addTest(s)
modules_count += 1
tests_count += test_count
print('Total: %s tests in %s modules' % (tests_count, modules_count))
# TODO: Pass this off to unittest.main()
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
finally:
os.chdir(cwd)
if __name__ == '__main__':
main()
......@@ -6,7 +6,7 @@ import subprocess
if sys.argv[1:] == []:
os.environ['GEVENT_BACKEND'] = 'select'
popen = subprocess.Popen([sys.executable, 'test__environ.py', '1'])
popen = subprocess.Popen([sys.executable, __file__, '1'])
assert popen.wait() == 0, popen.poll()
else:
hub = gevent.get_hub()
......
......@@ -5,13 +5,13 @@ import weakref
import gevent
from gevent.event import Event, AsyncResult
import greentest
import gevent.testing as greentest
from greentest.six import xrange
from greentest.timing import AbstractGenericGetTestCase
from greentest.timing import AbstractGenericWaitTestCase
from greentest.timing import SMALL_TICK
from greentest.timing import SMALL_TICK_MAX_ADJ
from gevent.testing.six import xrange
from gevent.testing.timing import AbstractGenericGetTestCase
from gevent.testing.timing import AbstractGenericWaitTestCase
from gevent.testing.timing import SMALL_TICK
from gevent.testing.timing import SMALL_TICK_MAX_ADJ
DELAY = SMALL_TICK + SMALL_TICK_MAX_ADJ
......
from gevent.socket import create_connection, timeout
import greentest
import gevent.testing as greentest
import gevent
from greentest import util
from greentest import params
from gevent.testing import util
from gevent.testing import params
class Test(util.TestServer):
server = 'echoserver.py'
......
......@@ -8,8 +8,8 @@ from time import sleep
import gevent
from gevent.server import StreamServer
import greentest
from greentest import util
import gevent.testing as greentest
from gevent.testing import util
@greentest.skipOnLibuvOnCIOnPyPy("Timing issues sometimes lead to connection refused")
class Test(util.TestServer):
......
from gevent import monkey; monkey.patch_all(subprocess=True)
from gevent import monkey
monkey.patch_all(subprocess=True)
import sys
from gevent.server import DatagramServer
from unittest import TestCase
from greentest.util import run
from greentest import main
class Test_udp_client(TestCase):
from gevent.testing.util import run
from gevent.testing import util
from gevent.testing import main
class Test_udp_client(util.TestServer):
def test(self):
log = []
......@@ -18,7 +21,7 @@ class Test_udp_client(TestCase):
server.start()
try:
run([sys.executable, '-W', 'ignore', '-u', 'udp_client.py', 'Test_udp_client'],
timeout=10, cwd='../../examples/')
timeout=10, cwd=self.cwd)
finally:
server.close()
self.assertEqual(log, [b'Test_udp_client'])
......
import socket
from greentest import util
from greentest import main
from gevent.testing import util
from gevent.testing import main
class Test(util.TestServer):
......
......@@ -3,8 +3,8 @@ import os
import glob
import time
import greentest
from greentest import util
import gevent.testing as greentest
from gevent.testing import util
cwd = '../../examples/'
......
import gevent
import sys
import greentest
from greentest import six
from greentest import ExpectedException as ExpectedError
import gevent.testing as greentest
from gevent.testing import six
from gevent.testing import ExpectedException as ExpectedError
if not six.PY3:
sys.exc_clear()
......
import unittest
import warnings
from greentest.modules import walk_modules
from greentest import main
from greentest.sysinfo import NON_APPLICABLE_SUFFIXES
from gevent.testing.modules import walk_modules
from gevent.testing import main
from gevent.testing.sysinfo import NON_APPLICABLE_SUFFIXES
from greentest import six
from gevent.testing import six
class TestExec(unittest.TestCase):
......@@ -14,28 +15,25 @@ class TestExec(unittest.TestCase):
def make_exec_test(path, module):
def test(self):
#sys.stderr.write('%s %s\n' % (module, path))
def test(_):
with open(path, 'rb') as f:
src = f.read()
six.exec_(src, {'__file__': path})
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
six.exec_(src, {'__file__': path})
name = "test_" + module.replace(".", "_")
test.__name__ = name
setattr(TestExec, name, test)
def make_all_tests():
for path, module in walk_modules(recursive=True):
if module.endswith(NON_APPLICABLE_SUFFIXES):
continue
make_exec_test(path, module)
for path, module in walk_modules():
ignored = False
for x in NON_APPLICABLE_SUFFIXES:
if module.endswith(x):
ignored = True
break
if ignored:
continue
make_exec_test(path, module)
make_all_tests()
if __name__ == '__main__':
main()
......@@ -8,11 +8,11 @@ import unittest
import gevent
from gevent.fileobject import FileObject, FileObjectThread
import greentest
from greentest.sysinfo import PY3
from greentest.flaky import reraiseFlakyTestRaceConditionLibuv
from greentest.skipping import skipOnLibuvOnCIOnPyPy
from greentest.skipping import skipOnWindows
import gevent.testing as greentest
from gevent.testing.sysinfo import PY3
from gevent.testing.flaky import reraiseFlakyTestRaceConditionLibuv
from gevent.testing.skipping import skipOnLibuvOnCIOnPyPy
from gevent.testing.skipping import skipOnWindows
try:
ResourceWarning
......
......@@ -21,9 +21,9 @@ import sys
import gevent
from gevent import socket
from greentest import TestCase, main, tcp_listener
from greentest import skipOnPyPy
from greentest import params
from gevent.testing import TestCase, main, tcp_listener
from gevent.testing import skipOnPyPy
from gevent.testing import params
......
......@@ -21,7 +21,7 @@
import re
import unittest
import greentest
import gevent.testing as greentest
import gevent
from gevent import sleep, with_timeout, getcurrent
......@@ -29,9 +29,9 @@ from gevent import greenlet
from gevent.event import AsyncResult
from gevent.queue import Queue, Channel
from greentest.timing import AbstractGenericWaitTestCase
from greentest.timing import AbstractGenericGetTestCase
from greentest import timing
from gevent.testing.timing import AbstractGenericWaitTestCase
from gevent.testing.timing import AbstractGenericGetTestCase
from gevent.testing import timing
DELAY = timing.SMALL_TICK
greentest.TestCase.error_fatal = False
......
from __future__ import print_function, division, absolute_import
import time
import greentest
import gevent.testing as greentest
from greentest import timing
from gevent.testing import timing
import gevent
from gevent import pool
from gevent.timeout import Timeout
......@@ -142,7 +142,7 @@ class Test(greentest.TestCase):
def f():
try:
gevent.sleep(1.5)
except:
except: # pylint:disable=bare-except
gevent.sleep(1)
p1 = GreenletSubclass.spawn(f)
p2 = GreenletSubclass.spawn(f)
......
......@@ -26,7 +26,7 @@ If either operation blocked the whole script would block and timeout.
from gevent import monkey
monkey.patch_all()
import greentest
import gevent.testing as greentest
try:
import urllib2
......@@ -38,7 +38,7 @@ except ImportError:
from http import server as BaseHTTPServer
import gevent
from greentest import params
from gevent.testing import params
class TestGreenness(greentest.TestCase):
......
......@@ -22,8 +22,8 @@
import re
import time
import greentest
import greentest.timing
import gevent.testing as greentest
import gevent.testing.timing
import gevent
from gevent import socket
......@@ -78,7 +78,7 @@ class TestExceptionInMainloop(greentest.TestCase):
class TestSleep(greentest.timing.AbstractGenericWaitTestCase):
class TestSleep(gevent.testing.timing.AbstractGenericWaitTestCase):
def wait(self, timeout):
gevent.sleep(timeout)
......@@ -87,7 +87,7 @@ class TestSleep(greentest.timing.AbstractGenericWaitTestCase):
gevent.sleep(0)
class TestWaiterGet(greentest.timing.AbstractGenericWaitTestCase):
class TestWaiterGet(gevent.testing.timing.AbstractGenericWaitTestCase):
def setUp(self):
super(TestWaiterGet, self).setUp()
......
import unittest
import gevent
class Test(unittest.TestCase):
def test(self):
# hub.join() guarantees that loop has exited cleanly
res = gevent.get_hub().join()
self.assertTrue(res)
res = gevent.get_hub().join()
self.assertTrue(res)
# but it is still possible to use gevent afterwards
gevent.sleep(0.01)
res = gevent.get_hub().join()
self.assertTrue(res)
if __name__ == '__main__':
unittest.main()
import functools
import unittest
import gevent
import gevent.core
from gevent.event import Event
from gevent.testing.testcase import TimeAssertMixin
SMALL_TICK = 0.05
# setting up signal does not affect join()
gevent.signal(1, lambda: None) # wouldn't work on windows
def repeated(func, repetitions=2):
@functools.wraps(func)
def f(self):
for _ in range(repetitions):
func(self)
return f
class Test(TimeAssertMixin, unittest.TestCase):
@repeated
def test_callback(self):
# exiting because the spawned greenlet finished execution (spawn (=callback) variant)
x = gevent.spawn(lambda: 5)
with self.runs_in_no_time():
result = gevent.wait(timeout=10)
self.assertTrue(result)
self.assertTrue(x.dead, x)
self.assertEqual(x.value, 5)
@repeated
def test_later(self):
# exiting because the spawned greenlet finished execution (spawn_later (=timer) variant)
x = gevent.spawn_later(SMALL_TICK, lambda: 5)
with self.runs_in_given_time(SMALL_TICK):
result = gevent.wait(timeout=10)
self.assertTrue(result)
self.assertTrue(x.dead, x)
@repeated
def test_timeout(self):
# exiting because of timeout (the spawned greenlet still runs)
x = gevent.spawn_later(10, lambda: 5)
with self.runs_in_given_time(SMALL_TICK):
result = gevent.wait(timeout=SMALL_TICK)
self.assertFalse(result)
self.assertFalse(x.dead, x)
x.kill()
with self.runs_in_no_time():
result = gevent.wait()
self.assertTrue(result)
@repeated
def test_event(self):
# exiting because of event (the spawned greenlet still runs)
x = gevent.spawn_later(10, lambda: 5)
event = Event()
event_set = gevent.spawn_later(SMALL_TICK, event.set)
with self.runs_in_given_time(SMALL_TICK):
result = gevent.wait([event])
self.assertEqual(result, [event])
self.assertFalse(x.dead, x)
self.assertTrue(event_set.dead)
self.assertTrue(event.is_set)
x.kill()
with self.runs_in_no_time():
result = gevent.wait()
self.assertTrue(result)
@repeated
def test_ref_arg(self):
# checking "ref=False" argument
gevent.get_hub().loop.timer(10, ref=False).start(lambda: None)
with self.runs_in_no_time():
result = gevent.wait()
self.assertTrue(result)
@repeated
def test_ref_attribute(self):
# checking "ref=False" attribute
w = gevent.get_hub().loop.timer(10)
w.start(lambda: None)
w.ref = False
with self.runs_in_no_time():
result = gevent.wait()
self.assertTrue(result)
class TestAgain(Test):
"Repeat the same tests"
if __name__ == '__main__':
unittest.main()
import sys
import unittest
@unittest.skipUnless(
sys.version_info[0] == 2,
"Only on Python 2"
)
class Test(unittest.TestCase):
def test(self):
import threading
import gevent.monkey
gevent.monkey.patch_all()
import gevent
self.assertIs(threading._sleep, gevent.sleep)
if __name__ == '__main__':
unittest.main()
# A greenlet that's killed before it is ever started
# should never be switched to
import gevent
import greentest
import gevent.testing as greentest
class MyException(Exception):
......
......@@ -23,7 +23,7 @@ def main():
workers = [gevent.spawn(worker, i) for i in range(3)]
workers.append(done_worker)
for g in gevent.iwait(workers):
for _ in gevent.iwait(workers):
finished += 1
# Simulate doing something that causes greenlets to switch;
# a non-zero timeout is crucial
......
......@@ -10,7 +10,7 @@ import sys
from multiprocessing import Process
from subprocess import Popen, PIPE
import greentest
import gevent.testing as greentest
def f(sleep_sec):
gevent.sleep(sleep_sec)
......
# A greenlet that's killed with an exception should fail.
import greentest
import gevent.testing as greentest
import gevent
......
......@@ -29,10 +29,10 @@ else:
import time
import unittest
import greentest
from greentest.sysinfo import CFFI_BACKEND
from greentest.sysinfo import RUN_COVERAGE
from greentest.sysinfo import WIN
import gevent.testing as greentest
from gevent.testing.sysinfo import CFFI_BACKEND
from gevent.testing.sysinfo import RUN_COVERAGE
from gevent.testing.sysinfo import WIN
class Test(unittest.TestCase):
......
import gevent
import greentest
import gevent.testing as greentest
from gevent.lock import Semaphore
......
import greentest
import gevent.testing as greentest
from copy import copy
# Comment the line below to see that the standard thread.local is working correct
from gevent import monkey; monkey.patch_all()
......@@ -160,7 +160,7 @@ class TestGeventLocal(greentest.TestCase):
self.assertEqual(a.initialized, 2)
# The slot overrides dict values
a.__dict__['initialized'] = 42
a.__dict__['initialized'] = 42 # pylint:disable=unsupported-assignment-operation
self.assertEqual(a.initialized, 2)
# Deleting the slot deletes the slot, but not the dict
......@@ -341,19 +341,26 @@ class TestGeventLocal(greentest.TestCase):
self.assertEqual(count, len(deleted_sentinels))
@greentest.skipOnPyPy("GC makes this non-deterministic, especially on Windows")
@greentest.ignores_leakcheck
def test_local_dicts_for_greenlet(self):
# In fact, only on Windows do we see gc being an issue;
# pypy2 5.10 on macOS and Travis don't have a problem.
import gevent
from gevent.local import all_local_dicts_for_greenlet
x = MyLocal()
x.foo = 42
del x.sentinel
results = all_local_dicts_for_greenlet(gevent.getcurrent())
self.assertEqual(results,
[((MyLocal, id(x)), {'foo': 42})])
class MyGreenlet(gevent.Greenlet):
results = None
id_x = None
def _run(self): # pylint:disable=method-hidden
x = local()
x.foo = 42
self.id_x = id(x)
self.results = all_local_dicts_for_greenlet(self)
g = MyGreenlet()
g.start()
g.join()
self.assertTrue(g.successful, g)
self.assertEqual(g.results,
[((local, g.id_x), {'foo': 42})])
def test_local_with_abc(self):
# an ABC (or generally any non-exact-type) in the MRO doesn't
......
......@@ -9,11 +9,11 @@ import errno
import weakref
import greentest
import gevent.testing as greentest
dirname = os.path.dirname(os.path.abspath(__file__))
certfile = os.path.join(dirname, '2.7/keycert.pem')
certfile = os.path.join(dirname, '2_7_keycert.pem')
pid = os.getpid()
PY3 = greentest.PY3
......@@ -26,7 +26,7 @@ if PY3:
fd_types = (int, long)
WIN = greentest.WIN
from greentest import get_open_files
from gevent.testing import get_open_files
try:
import psutil
except ImportError:
......
import sys
import unittest
from greentest import TestCase, main
from gevent.testing import TestCase, main
import gevent
from gevent.timeout import Timeout
@unittest.skipUnless(
hasattr(sys, 'gettotalrefcount'),
"Needs debug build"
)
class TestQueue(TestCase):
# pylint:disable=bare-except,no-member
def test(self):
result = ''
......@@ -43,12 +47,10 @@ class TestQueue(TestCase):
result += '%s' % sys.gettotalrefcount()
a, b, c = result.split()
_, b, c = result.split()
assert b == c, 'total refcount mismatch: %s' % result
if not hasattr(sys, 'gettotalrefcount'):
del TestQueue
if __name__ == '__main__':
main()
......@@ -5,7 +5,7 @@ monkey.patch_all()
import sys
import unittest
from greentest.testcase import SubscriberCleanupMixin
from gevent.testing.testcase import SubscriberCleanupMixin
class TestMonkey(SubscriberCleanupMixin, unittest.TestCase):
......
......@@ -16,7 +16,7 @@ def _inner_lock(lock):
def checkLocks(kind, ignore_none=True):
handlers = logging._handlerList
assert len(handlers) > 0
assert handlers
for weakref in handlers:
# In py26, these are actual handlers, not weakrefs
......
# Some simple queue module tests, plus some failure conditions
# to ensure the Queue locks remain stable.
from gevent import monkey; monkey.patch_all()
from gevent import monkey
monkey.patch_all()
from gevent import queue as Queue
import threading
import time
......
......@@ -10,6 +10,13 @@ from subprocess import PIPE
class TestRun(unittest.TestCase):
maxDiff = None
def setUp(self):
self.cwd = os.getcwd()
os.chdir(os.path.dirname(__file__))
def tearDown(self):
os.chdir(self.cwd)
def _run(self, script):
env = os.environ.copy()
env['PYTHONWARNINGS'] = 'ignore'
......
import sys
import greentest
import gevent.testing as greentest
try:
import selectors # Do this before the patch, just to force it
except ImportError:
......
......@@ -11,7 +11,7 @@ pid = None
awaiting_child = []
def handle_sigchld(*args):
def handle_sigchld(*_args):
# Make sure we can do a blocking operation
gevent.sleep()
# Signal completion
......
......@@ -16,12 +16,12 @@ import sys
import signal
import subprocess
def _waitpid(pid):
def _waitpid(p):
try:
_, stat = os.waitpid(pid, 0)
_, stat = os.waitpid(p, 0)
except OSError:
# Interrupted system call
_, stat = os.waitpid(pid, 0)
_, stat = os.waitpid(p, 0)
assert stat == 0, stat
if hasattr(signal, 'SIGCHLD'):
......
# test for issue #210
from gevent import core
from greentest.util import alarm
from gevent.testing.util import alarm
alarm(1)
......
import gevent
import greentest
from greentest.six import xrange
import gevent.testing as greentest
from gevent.testing.six import xrange
class appender(object):
......
......@@ -6,12 +6,12 @@ from os import pipe
import gevent
from gevent import os
from greentest import TestCase, main, LARGE_TIMEOUT
from gevent.testing import TestCase, main, LARGE_TIMEOUT
from gevent import Greenlet, joinall
from greentest import mock
from greentest import six
from greentest.skipping import skipOnLibuvOnPyPyOnWin
from gevent.testing import mock
from gevent.testing import six
from gevent.testing.skipping import skipOnLibuvOnPyPyOnWin
class TestOS_tp(TestCase):
......
......@@ -4,10 +4,10 @@ import gevent.pool
from gevent.event import Event
from gevent.queue import Queue
import greentest
import greentest.timing
import gevent.testing as greentest
import gevent.testing.timing
import random
from greentest import ExpectedException
from gevent.testing import ExpectedException
import unittest
......@@ -78,7 +78,7 @@ class TestCoroutinePool(unittest.TestCase):
timer_fired.append(True)
def some_work():
gevent.timer(0, fire_timer)
gevent.timer(0, fire_timer) # pylint:disable=no-member
pool = self.klass(2)
pool.apply(some_work)
......@@ -492,7 +492,7 @@ class TestPool0(greentest.TestCase):
self.assertEqual(0, p.wait_available(timeout=0.01))
class TestJoinSleep(greentest.timing.AbstractGenericWaitTestCase):
class TestJoinSleep(gevent.testing.timing.AbstractGenericWaitTestCase):
def wait(self, timeout):
p = gevent.pool.Pool()
......@@ -503,7 +503,7 @@ class TestJoinSleep(greentest.timing.AbstractGenericWaitTestCase):
g.kill()
class TestJoinSleep_raise_error(greentest.timing.AbstractGenericWaitTestCase):
class TestJoinSleep_raise_error(gevent.testing.timing.AbstractGenericWaitTestCase):
def wait(self, timeout):
p = gevent.pool.Pool()
......
......@@ -43,9 +43,9 @@ import weakref
from wsgiref.validate import validator
import greentest
import gevent.testing as greentest
import gevent
from greentest import PY3, PYPY
from gevent.testing import PY3, PYPY
from gevent import socket
from gevent import pywsgi
from gevent.pywsgi import Input
......@@ -611,10 +611,12 @@ class TestChunkedPost(TestCase):
if env['PATH_INFO'] == '/a':
data = env['wsgi.input'].read(6)
return [data]
elif env['PATH_INFO'] == '/b':
if env['PATH_INFO'] == '/b':
lines = [x for x in iter(lambda: env['wsgi.input'].read(6), b'')]
return lines
elif env['PATH_INFO'] == '/c':
if env['PATH_INFO'] == '/c':
return [x for x in iter(lambda: env['wsgi.input'].read(1), b'')]
def test_014_chunked_post(self):
......@@ -749,7 +751,7 @@ class HttpsTestCase(TestCase):
import ssl
raw_sock = self.connect()
sock = ssl.wrap_socket(raw_sock)
fd = sock.makefile(bufsize=1)
fd = sock.makefile(bufsize=1) # pylint:disable=unexpected-keyword-arg
fd.write('%s / HTTP/1.1\r\nHost: localhost\r\n' % method)
if post_body is not None:
fd.write('Content-Length: %s\r\n\r\n' % len(post_body))
......
import unittest
import greentest
from greentest import TestCase, main
import gevent.testing as greentest
from gevent.testing import TestCase, main
import gevent
from gevent.hub import get_hub, LoopExit
from gevent import util
from gevent import queue
from gevent.queue import Empty, Full
from gevent.event import AsyncResult
from greentest.timing import AbstractGenericGetTestCase
from gevent.testing.timing import AbstractGenericGetTestCase
# pylint:disable=too-many-ancestors
......
......@@ -23,7 +23,7 @@
are not leaked by the hub.
"""
from __future__ import print_function
from _socket import socket
from _socket import socket as c_socket
import sys
if sys.version_info[0] >= 3:
# Python3 enforces that __weakref__ appears only once,
......@@ -32,17 +32,17 @@ if sys.version_info[0] >= 3:
# (because socket.socket defines __slots__ with __weakref__),
# so import socket.socket before that can happen.
__import__('socket')
Socket = socket
Socket = c_socket
else:
class Socket(socket):
class Socket(c_socket):
"Something we can have a weakref to"
import _socket
_socket.socket = Socket
import greentest
import gevent.testing as greentest
from gevent import monkey; monkey.patch_all()
from greentest import flaky
from gevent.testing import flaky
from pprint import pformat
try:
......@@ -117,7 +117,7 @@ def run_interaction(run_client):
# strong refs to the socket still around.
try:
sleep(0.1 + SOCKET_TIMEOUT)
except Exception:
except Exception: # pylint:disable=broad-except
pass
return w
......@@ -139,8 +139,9 @@ def run_and_check(run_client):
@greentest.skipOnCI("Often fail with timeouts or force closed connections; not sure why.")
@greentest.skipIf(greentest.RUN_LEAKCHECKS and greentest.PY3,
"Often fail with force closed connections; not sure why. "
@greentest.skipIf(
greentest.RUN_LEAKCHECKS and greentest.PY3,
"Often fail with force closed connections; not sure why. "
)
class Test(greentest.TestCase):
......
from greentest import six
from gevent.testing import six
import sys
import os
import errno
from gevent import select, socket
import gevent.core
import greentest
import greentest.timing
import gevent.testing as greentest
import gevent.testing.timing
import unittest
class TestSelect(greentest.timing.AbstractGenericWaitTestCase):
class TestSelect(gevent.testing.timing.AbstractGenericWaitTestCase):
def wait(self, timeout):
select.select([], [], [], timeout)
......@@ -17,7 +17,7 @@ class TestSelect(greentest.timing.AbstractGenericWaitTestCase):
@greentest.skipOnWindows("Cant select on files")
class TestSelectRead(greentest.timing.AbstractGenericWaitTestCase):
class TestSelectRead(gevent.testing.timing.AbstractGenericWaitTestCase):
def wait(self, timeout):
r, w = os.pipe()
......@@ -49,7 +49,7 @@ class TestSelectRead(greentest.timing.AbstractGenericWaitTestCase):
@unittest.skipUnless(hasattr(select, 'poll'), "Needs poll")
@greentest.skipOnWindows("Cant poll on files")
class TestPollRead(greentest.timing.AbstractGenericWaitTestCase):
class TestPollRead(gevent.testing.timing.AbstractGenericWaitTestCase):
def wait(self, timeout):
# On darwin, the read pipe is reported as writable
# immediately, for some reason. So we carefully register
......
import greentest
import gevent.testing as greentest
import gevent
from gevent.lock import Semaphore
from gevent.thread import allocate_lock
......
......@@ -4,9 +4,9 @@ import errno
import os
import greentest
from greentest import PY3
from greentest import DEFAULT_SOCKET_TIMEOUT as _DEFAULT_SOCKET_TIMEOUT
import gevent.testing as greentest
from gevent.testing import PY3
from gevent.testing import DEFAULT_SOCKET_TIMEOUT as _DEFAULT_SOCKET_TIMEOUT
from gevent import socket
import gevent
from gevent.server import StreamServer
......@@ -14,7 +14,7 @@ from gevent.server import StreamServer
class SimpleStreamServer(StreamServer):
def handle(self, client_socket, _address):
def handle(self, client_socket, _address): # pylint:disable=method-hidden
fd = client_socket.makefile()
try:
request_line = fd.readline()
......@@ -286,6 +286,7 @@ class TestDefaultSpawn(TestCase):
def test_invalid_callback(self):
self._test_invalid_callback()
@greentest.reraises_flaky_timeout(socket.timeout)
def _test_serve_forever(self):
g = gevent.spawn(self.server.serve_forever)
try:
......@@ -487,7 +488,7 @@ class TestSSLGetCertificate(TestCase):
self.init_server()
server_host, server_port, _family = self.get_server_host_port_family()
ssl.get_server_certificate((server_host, server_port))
ssl.get_server_certificate((server_host, server_port)) # pylint:disable=no-member
def test_wrap_socket_and_handle_wrap_failure(self):
......
import socket
import greentest
import gevent.testing as greentest
import gevent
from gevent import pywsgi
......
from __future__ import print_function
import signal
import greentest
import gevent.testing as greentest
import gevent
import pkg_resources
try:
cffi_version = pkg_resources.get_distribution('cffi').parsed_version
except Exception:
except Exception: # pylint:disable=broad-except
# No cffi installed. Shouldn't happen to gevent standard tests,
# but maybe some downstream distributor removed it.
cffi_version = None
......@@ -50,7 +50,7 @@ if hasattr(signal, 'SIGALRM'):
except Expected as ex:
assert str(ex) == 'TestSignal', ex
finally:
sig.cancel()
sig.cancel() # pylint:disable=no-member
@greentest.skipIf((greentest.PY3
......
import gevent
from greentest.util import alarm
from gevent.testing.util import alarm
alarm(3)
......
......@@ -7,10 +7,10 @@ import socket
import traceback
import time
import unittest
import greentest
import gevent.testing as greentest
from functools import wraps
from greentest import six
from greentest import LARGE_TIMEOUT
from gevent.testing import six
from gevent.testing import LARGE_TIMEOUT
# we use threading on purpose so that we can test both regular and gevent sockets with the same code
from threading import Thread as _Thread
......@@ -320,7 +320,7 @@ class TestTCP(greentest.TestCase):
# Issue 944
# If we have SOCK_CLOEXEC or similar, we shouldn't be passing
# them through to the getaddrinfo call that connect() makes
SOCK_CLOEXEC = socket.SOCK_CLOEXEC
SOCK_CLOEXEC = socket.SOCK_CLOEXEC # pylint:disable=no-member
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM | SOCK_CLOEXEC)
def accept_once():
......@@ -421,7 +421,7 @@ class TestFunctions(greentest.TestCase):
gevent.sleep(10)
with self.assertRaises(gevent.socket.timeout):
gevent.socket.wait(io(), timeout=0.01)
gevent.socket.wait(io(), timeout=0.01) # pylint:disable=no-member
def test_signatures(self):
......
import gevent
from gevent import socket
from gevent import server
import greentest
import gevent.testing as greentest
# XXX also test: send, sendall, recvfrom, recvfrom_into, sendto
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
# pylint:disable=broad-except
import gevent
from gevent import monkey
import os
import re
import greentest
import gevent.testing as greentest
import unittest
import socket
from time import time
import traceback
import gevent.socket as gevent_socket
from greentest.util import log
from greentest import six
from greentest.six import xrange
from gevent.testing.util import log
from gevent.testing import six
from gevent.testing.six import xrange
resolver = gevent.get_hub().resolver
......@@ -23,10 +23,10 @@ log('Resolver: %s', resolver)
if getattr(resolver, 'pool', None) is not None:
resolver.pool.size = 1
from greentest.sysinfo import RESOLVER_NOT_SYSTEM
from greentest.sysinfo import RESOLVER_DNSPYTHON
from greentest.sysinfo import PY2
import greentest.timing
from gevent.testing.sysinfo import RESOLVER_NOT_SYSTEM
from gevent.testing.sysinfo import RESOLVER_DNSPYTHON
from gevent.testing.sysinfo import PY2
import gevent.testing.timing
assert gevent_socket.gaierror is socket.gaierror
......@@ -83,9 +83,9 @@ def run(function, *args):
return result, delta
def log_call(result, time, function, *args):
def log_call(result, runtime, function, *args):
log(format_call(function, args))
log_fresult(result, time)
log_fresult(result, runtime)
def compare_relaxed(a, b):
......@@ -332,9 +332,11 @@ class TestCase(greentest.TestCase):
# If we're using the ares resolver, allow the real resolver to generate an
# error that the ares resolver actually gets an answer to.
if (RESOLVER_NOT_SYSTEM
and isinstance(real_result, errors)
and not isinstance(gevent_result, errors)):
if (
RESOLVER_NOT_SYSTEM
and isinstance(real_result, errors)
and not isinstance(gevent_result, errors)
):
return
# From 2.7 on, assertEqual does a better job highlighting the results than we would
......@@ -453,7 +455,7 @@ class SanitizedHostsFile(HostsFile):
# the system's etc hosts?
class TestEtcHosts(TestCase):
MAX_HOSTS = os.getenv('GEVENTTEST_MAX_ETC_HOSTS', 10)
MAX_HOSTS = int(os.getenv('GEVENTTEST_MAX_ETC_HOSTS', '10'))
@classmethod
def populate_tests(cls):
......@@ -493,7 +495,7 @@ class TestFamily(TestCase):
cls._result = getattr(socket, 'getaddrinfo')(TestGeventOrg.HOSTNAME, None)
return cls._result
def assert_error(self, error, function, *args):
def assert_error(self, error, function, *args): # pylint:disable=arguments-differ
try:
result = function(*args)
raise AssertionError('%s: Expected to raise %s, instead returned %r' % (function, error, result))
......@@ -574,7 +576,7 @@ add(TestInternational, u'президент.рф', 'russian',
add(TestInternational, u'президент.рф'.encode('idna'), 'idna')
class TestInterrupted_gethostbyname(greentest.timing.AbstractGenericWaitTestCase):
class TestInterrupted_gethostbyname(gevent.testing.timing.AbstractGenericWaitTestCase):
# There are refs to a Waiter in the C code that don't go
# away yet; one gc may or may not do it.
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
import greentest
import gevent.testing as greentest
import socket
from test__socket_dns import TestCase, add
from greentest.sysinfo import RESOLVER_NOT_SYSTEM
from greentest.sysinfo import RESOLVER_DNSPYTHON
from gevent.testing.sysinfo import RESOLVER_NOT_SYSTEM
from gevent.testing.sysinfo import RESOLVER_DNSPYTHON
if not greentest.RUNNING_ON_CI and not RESOLVER_DNSPYTHON:
......
......@@ -19,7 +19,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import greentest
import gevent.testing as greentest
from gevent.socket import socket, error
try:
......
import greentest
import gevent.testing as greentest
from gevent import socket
import errno
import sys
......
#!/usr/bin/python
from gevent import monkey; monkey.patch_all()
import sys
import greentest
from gevent import monkey
monkey.patch_all()
import unittest
try:
import httplib
except ImportError:
from http import client as httplib
import socket
if not hasattr(socket, 'ssl'):
sys.exit(0)
import gevent.testing as greentest
@unittest.skipUnless(
hasattr(socket, 'ssl'),
"Needs socket.ssl"
)
class AmazonHTTPSTests(greentest.TestCase):
__timeout__ = 30
......@@ -25,7 +30,7 @@ class AmazonHTTPSTests(greentest.TestCase):
def test_str_and_repr(self):
conn = socket.socket()
conn.connect(('sdb.amazonaws.com', 443))
ssl_conn = socket.ssl(conn)
ssl_conn = socket.ssl(conn) # pylint:disable=no-member
assert str(ssl_conn)
assert repr(ssl_conn)
......
import gevent
from gevent import socket
import greentest
import gevent.testing as greentest
class Test(greentest.TestCase):
......
......@@ -2,7 +2,7 @@ from gevent import monkey; monkey.patch_all()
import os
import socket
import greentest
import gevent.testing as greentest
# Be careful not to have TestTCP as a bare attribute in this module,
# even aliased, to avoid running duplicate tests
import test__socket
......@@ -28,7 +28,7 @@ class TestSSL(test__socket.TestTCP):
self._close_on_teardown(raw_listener)
return listener
def create_connection(self, *args, **kwargs):
def create_connection(self, *args, **kwargs): # pylint:disable=arguments-differ
return ssl.wrap_socket(super(TestSSL, self).create_connection(*args, **kwargs))
# The SSL library can take a long time to buffer the large amount of data we're trying
......
......@@ -7,9 +7,9 @@ import time
import gc
import tempfile
import greentest
import gevent.testing as greentest
import gevent
from greentest import mock
from gevent.testing import mock
from gevent import subprocess
if not hasattr(subprocess, 'mswindows'):
......@@ -222,7 +222,7 @@ class Test(greentest.TestCase):
def test_check_output_keyword_error(self):
try:
subprocess.check_output([sys.executable, '-c', 'import sys; sys.exit(44)'])
except subprocess.CalledProcessError as e:
except subprocess.CalledProcessError as e: # pylint:disable=no-member
self.assertEqual(e.returncode, 44)
else:
raise AssertionError('must fail with CalledProcessError')
......@@ -282,7 +282,6 @@ class Test(greentest.TestCase):
# If the file is in universal_newlines mode, we should always get a str when
# there is no output.
# https://github.com/gevent/gevent/pull/939
kwargs = {'universal_newlines': True}
self.__test_no_output({'universal_newlines': True}, str)
@greentest.skipIf(sys.version_info[:2] < (3, 6), "Need encoding argument")
......@@ -386,7 +385,7 @@ class TestFDs(unittest.TestCase):
class RunFuncTestCase(greentest.TestCase):
# Based on code from python 3.6
__timeout__ = 6
__timeout__ = greentest.LARGE_TIMEOUT
def run_python(self, code, **kwargs):
"""Run Python code in a subprocess using subprocess.run"""
......@@ -397,11 +396,11 @@ class RunFuncTestCase(greentest.TestCase):
# call() function with sequence argument
cp = self.run_python("import sys; sys.exit(47)")
self.assertEqual(cp.returncode, 47)
with self.assertRaises(subprocess.CalledProcessError):
with self.assertRaises(subprocess.CalledProcessError): # pylint:disable=no-member
cp.check_returncode()
def test_check(self):
with self.assertRaises(subprocess.CalledProcessError) as c:
with self.assertRaises(subprocess.CalledProcessError) as c: # pylint:disable=no-member
self.run_python("import sys; sys.exit(47)", check=True)
self.assertEqual(c.exception.returncode, 47)
......
import sys
from gevent.subprocess import Popen
from greentest.util import alarm
from gevent.testing.util import alarm
alarm(3)
......
import sys
import greentest
import gevent.testing as greentest
import gevent
from gevent.hub import get_hub
......
......@@ -5,7 +5,7 @@ import gevent.hub
assert gevent.hub._get_hub() is None, 'monkey.patch_all() should not init hub'
import gevent
import greentest
import gevent.testing as greentest
import threading
......
# testing gevent's Event, Lock, RLock, Semaphore, BoundedSemaphore with standard test_threading
from __future__ import print_function
from greentest.six import xrange
import greentest
from gevent.testing.six import xrange
import gevent.testing as greentest
setup_ = '''from gevent import monkey; monkey.patch_all()
from gevent.event import Event
......@@ -29,10 +30,8 @@ setup_4 = '\n'.join(' %s' % line for line in setup_.split('\n'))
try:
from test import support
from test.support import verbose
except ImportError:
from test import test_support as support
from test.test_support import verbose
import random
import re
......@@ -50,6 +49,11 @@ import lock_tests
# A trivial mutable counter.
def skipDueToHang(cls):
return unittest.skipIf(
greentest.PYPY3 and greentest.RUNNING_ON_CI,
"SKIPPED: Timeout on PyPy3 on Travis"
)(cls)
class Counter(object):
def __init__(self):
......@@ -97,7 +101,7 @@ class TestThread(threading.Thread):
print('%s is finished. %d tasks are running' % (
self.name, self.nrunning.get()))
@skipDueToHang
class ThreadTests(unittest.TestCase):
# Create a bunch of threads, let each do some work, wait until all are
......@@ -231,6 +235,9 @@ class ThreadTests(unittest.TestCase):
worker_saw_exception = threading.Event()
class Worker(threading.Thread):
id = None
finished = False
def run(self):
self.id = thread.get_ident()
self.finished = False
......@@ -278,7 +285,7 @@ class ThreadTests(unittest.TestCase):
def test_limbo_cleanup(self):
# Issue 7481: Failure to start thread should cleanup the limbo map.
def fail_new_thread(*args):
def fail_new_thread(*_args):
raise thread.error()
_start_new_thread = threading._start_new_thread
threading._start_new_thread = fail_new_thread
......@@ -406,7 +413,7 @@ class ThreadTests(unittest.TestCase):
kwargs={'yet_another': self})
self.thread.start()
def _run(self, other_ref, yet_another):
def _run(self, _other_ref, _yet_another):
if self.should_raise:
raise SystemExit
......@@ -426,7 +433,7 @@ class ThreadTests(unittest.TestCase):
msg=('%d references still around' %
sys.getrefcount(weak_raising_cyclic_object())))
@skipDueToHang
class ThreadJoinOnShutdown(unittest.TestCase):
def _run_and_join(self, script):
......@@ -539,74 +546,65 @@ class ThreadJoinOnShutdown(unittest.TestCase):
self._run_and_join(script)
@skipDueToHang
class ThreadingExceptionTests(unittest.TestCase):
# A RuntimeError should be raised if Thread.start() is called
# multiple times.
# pylint:disable=bad-thread-instantiation
def test_start_thread_again(self):
thread = threading.Thread()
thread.start()
self.assertRaises(RuntimeError, thread.start)
thread_ = threading.Thread()
thread_.start()
self.assertRaises(RuntimeError, thread_.start)
def test_joining_current_thread(self):
current_thread = threading.current_thread()
self.assertRaises(RuntimeError, current_thread.join)
def test_joining_inactive_thread(self):
thread = threading.Thread()
self.assertRaises(RuntimeError, thread.join)
thread_ = threading.Thread()
self.assertRaises(RuntimeError, thread_.join)
def test_daemonize_active_thread(self):
thread = threading.Thread()
thread.start()
self.assertRaises(RuntimeError, setattr, thread, "daemon", True)
thread_ = threading.Thread()
thread_.start()
self.assertRaises(RuntimeError, setattr, thread_, "daemon", True)
@skipDueToHang
class LockTests(lock_tests.LockTests):
locktype = staticmethod(threading.Lock)
@skipDueToHang
class RLockTests(lock_tests.RLockTests):
locktype = staticmethod(threading.RLock)
@skipDueToHang
class NativeRLockTests(lock_tests.RLockTests):
# See comments at the top of the file for the difference
# between this and RLockTests, and why they both matter
locktype = staticmethod(threading.NativeRLock)
@skipDueToHang
class EventTests(lock_tests.EventTests):
eventtype = staticmethod(threading.Event)
@skipDueToHang
class ConditionAsRLockTests(lock_tests.RLockTests):
# An Condition uses an RLock by default and exports its API.
locktype = staticmethod(threading.Condition)
@skipDueToHang
class ConditionTests(lock_tests.ConditionTests):
condtype = staticmethod(threading.Condition)
@skipDueToHang
class SemaphoreTests(lock_tests.SemaphoreTests):
semtype = staticmethod(threading.Semaphore)
@skipDueToHang
class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests):
semtype = staticmethod(threading.BoundedSemaphore)
def main():
support.run_unittest(
LockTests, RLockTests, EventTests,
ConditionAsRLockTests, ConditionTests,
SemaphoreTests, BoundedSemaphoreTests,
ThreadTests,
ThreadJoinOnShutdown,
ThreadingExceptionTests,
NativeRLockTests,
)
if __name__ == "__main__":
if greentest.PYPY3 and greentest.RUNNING_ON_CI:
print("SKIPPED: Timeout on PyPy3 on Travis")
else:
greentest.main()
greentest.main()
......@@ -5,7 +5,7 @@ import threading
from gevent import monkey
monkey.patch_all()
import greentest
import gevent.testing as greentest
class Test(greentest.TestCase):
......
......@@ -3,7 +3,7 @@ from __future__ import print_function
import sys
import threading
from gevent import monkey
import greentest
import gevent.testing as greentest
class Test(greentest.TestCase):
......@@ -35,7 +35,7 @@ class Test(greentest.TestCase):
thread.start()
try:
thread.join()
except:
except: # pylint:disable=bare-except
# XXX: This can raise LoopExit in some cases.
greentest.reraiseFlakyTestRaceCondition()
......
......@@ -6,7 +6,7 @@
import threading
from time import sleep as time_sleep
import greentest
import gevent.testing as greentest
class NativeThread(threading.Thread):
do_run = True
......
from gevent import monkey; monkey.patch_all()
import threading
localdata = threading.local()
localdata.x = "hello"
assert localdata.x == 'hello'
......@@ -9,7 +10,7 @@ success = []
def func():
try:
localdata.x
getattr(localdata, 'x')
raise AssertionError('localdata.x must raise AttributeError')
except AttributeError:
pass
......
......@@ -3,7 +3,7 @@ import sys
import subprocess
import unittest
from gevent.thread import allocate_lock
import greentest
import gevent.testing as greentest
script = """
from gevent import monkey
......
......@@ -6,13 +6,13 @@ import random
import weakref
import gc
import greentest
import gevent.testing as greentest
import gevent.threadpool
from gevent.threadpool import ThreadPool
import gevent
from greentest import ExpectedException
from greentest import PYPY
from gevent.testing import ExpectedException
from gevent.testing import PYPY
......@@ -428,6 +428,7 @@ class TestMaxsize(TestCase):
class TestSize(TestCase):
@greentest.reraises_flaky_race_condition()
def test(self):
pool = self.pool = self._makeOne(2, increase=False)
self.assertEqual(pool.size, 0)
......
from __future__ import print_function
from gevent import monkey; monkey.patch_all()
import greentest
import gevent.testing as greentest
import gevent.threadpool
......
import greentest
import gevent.testing as greentest
import gevent
from gevent.hub import get_hub
import sys
......@@ -89,7 +89,7 @@ class Test(greentest.TestCase):
except TypeError as ex:
self.assertTrue(greentest.PY3, "Py3 raises a TypeError for non-BaseExceptions")
self.assert_type_err(ex)
except:
except: # pylint:disable=bare-except
self.assertTrue(greentest.PY2, "Old style classes can only be raised on Py2")
t = sys.exc_info()[0]
self.assertEqual(t, OldStyle)
......@@ -103,7 +103,7 @@ class Test(greentest.TestCase):
except TypeError as ex:
self.assertTrue(greentest.PY3, "Py3 raises a TypeError for non-BaseExceptions")
self.assert_type_err(ex)
except:
except: # pylint:disable=bare-except
self.assertTrue(greentest.PY2, "Old style classes can only be raised on Py2")
t = sys.exc_info()[0]
self.assertEqual(t, OldStyle)
......
......@@ -9,7 +9,7 @@ from __future__ import print_function
import gc
import unittest
import greentest
import gevent.testing as greentest
import gevent
from gevent import util
......
......@@ -2,3 +2,8 @@ test___monkey_patching.py
test__monkey_ssl_warning.py
test___monitor.py
test__monkey_scope.py
test__ares_timeout.py
test__close_backend_fd.py
test__hub_join.py
test__hub_join_timeout.py
test__issue112.py
......@@ -20,3 +20,7 @@ test___monitor.py
test__events.py
test__monkey_scope.py
test__iwait.py
test__ares_timeout.py
test__close_backend_fd.py
test__hub_join.py
test__hub_join_timeout.py
......@@ -2,9 +2,9 @@ test__all__.py
#uses socket test__api.py
test__api_timeout.py
test__ares_host_result.py
test_ares_timeout.py # explicitly uses ares resolver
test__ares_timeout.py # explicitly uses ares resolver
# uses socket test__backdoor.py
test_close_backend_fd.py
test__close_backend_fd.py
test__core_async.py
test__core_callback.py
test__core_loop_run.py
......@@ -30,10 +30,10 @@ test__GreenletExit.py
test__greenlet.py
test__greenletset.py
# uses socket test__greenness.py
test_hub_join.py
test_hub_join_timeout.py
test__hub_join.py
test__hub_join_timeout.py
# uses socket test__hub.py
test_issue112.py
test__issue112.py
test__joinall.py
test__local.py
test__loop_callback.py
......@@ -45,7 +45,7 @@ test__os.py
test__pool.py
# uses socket test__pywsgi.py
test__queue.py
test_queue.py
test__monkey_queue.py
# uses socket test__refcount.py
test__select.py
test__semaphore.py
......@@ -62,7 +62,7 @@ test__signal.py
test__subprocess_interrupted.py
test__subprocess.py
test__systemerror.py
test_threading_2.py
test__threading_2.py
test__threading_patched_local.py
test__threading_vs_settrace.py
test__threadpool.py
......
......@@ -667,7 +667,7 @@ def test_main(verbose=None):
# XXX: gevent: On windows with pypy2, some of these
# tests are incredibly slow or hang in shutdown for unknown
# reasons
import greentest
import gevent.testing as greentest
MySimpleHTTPRequestHandlerTestCase = SimpleHTTPRequestHandlerTestCase
MySimpleHTTPServerTestCase = SimpleHTTPServerTestCase
MyCGIHTTPServerTestCase = CGIHTTPServerTestCase
......
from __future__ import print_function
import sys
import errno
import gevent
try:
from gevent.resolver_ares import Resolver
except ImportError as ex:
print(ex)
sys.exit(0)
from gevent import socket
print(gevent.__file__)
address = ('', 7153)
listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
listener.bind(address)
except socket.error as ex:
if ex.errno in (errno.EPERM, errno.EADDRNOTAVAIL) or 'permission denied' in str(ex).lower():
sys.stderr.write('This test binds on port a port that was already in use or not allowed.\n')
sys.exit(0)
raise
def reader():
while True:
print(listener.recvfrom(10000))
gevent.spawn(reader)
r = gevent.get_hub().resolver = Resolver(servers=['127.0.0.1'], timeout=0.001, tries=1, udp_port=address[-1])
try:
result = r.gethostbyname('www.google.com')
except socket.gaierror as ex:
if 'ARES_ETIMEOUT' not in str(ex):
raise
else:
raise AssertionError('Expected timeout, got %r' % (result, ))
from __future__ import print_function
import os
import gevent
from gevent import core
if getattr(core, 'LIBEV_EMBED', False):
# hub.loop.fileno is only defined when
# we embed libev for some reason.
# Choosing specific backends is also only supported by libev
# (not libuv), and besides, libuv has a nasty tendency to
# abort() the process if its FD gets closed.
for count in range(2):
for backend in core.supported_backends():
hub = gevent.get_hub(backend, default=False)
assert hub.loop.backend == backend, (hub.loop.backend, backend)
gevent.sleep(0.001)
fileno = hub.loop.fileno()
if fileno is not None:
print('%s. Testing %r: %r' % (count, backend, hub))
os.close(fileno)
try:
gevent.sleep(0.001)
except SystemError as ex:
if '(libev)' in str(ex):
print('The error is expected: %s' % ex)
else:
raise
else:
raise AssertionError('gevent.sleep() is expected to fail after loop fd was closed')
else:
print('%s. %r lacks fileno()' % (count, backend))
hub.destroy()
assert 'destroyed' in repr(hub), repr(hub)
import gevent
# hub.join() guarantees that loop has exited cleanly
res = gevent.get_hub().join()
assert res is True, res
res = gevent.get_hub().join()
assert res is True, res
# but it is still possible to use gevent afterwards
gevent.sleep(0.01)
res = gevent.get_hub().join()
assert res is True, res
from contextlib import contextmanager
import gevent
import gevent.core
from gevent.event import Event
from time import time
from greentest.six import xrange
SMALL = 0.1
FUZZY = SMALL / 2
# setting up signal does not affect join()
gevent.signal(1, lambda: None) # wouldn't work on windows
from greentest import EXPECT_POOR_TIMER_RESOLUTION
EXPECT_POOR_TIMER_RESOLUTION = EXPECT_POOR_TIMER_RESOLUTION or hasattr(gevent.core, 'libuv')
# We observe longer/jittery timeouts running on appveyor or running with libuv
@contextmanager
def expected_time(expected, fuzzy=None):
if fuzzy is None:
if EXPECT_POOR_TIMER_RESOLUTION:
# The noted timer jitter issues on appveyor/pypy3
fuzzy = expected * 5.0
else:
fuzzy = expected / 2.0
start = time()
yield
elapsed = time() - start
assert expected - fuzzy <= elapsed <= expected + fuzzy, 'Expected: %r; elapsed: %r; fuzzy %r' % (expected, elapsed, fuzzy)
def no_time(fuzzy=(0.001 if not EXPECT_POOR_TIMER_RESOLUTION else 1.0)):
return expected_time(0, fuzzy=fuzzy)
for _a in xrange(2):
# exiting because the spawned greenlet finished execution (spawn (=callback) variant)
for _ in xrange(2):
x = gevent.spawn(lambda: 5)
with no_time(SMALL):
result = gevent.wait(timeout=10)
assert result is True, repr(result)
assert x.dead, x
assert x.value == 5, x
# exiting because the spawned greenlet finished execution (spawn_later (=timer) variant)
for _ in xrange(2):
x = gevent.spawn_later(SMALL, lambda: 5)
with expected_time(SMALL):
result = gevent.wait(timeout=10)
assert result is True, repr(result)
assert x.dead, x
# exiting because of timeout (the spawned greenlet still runs)
for _ in xrange(2):
x = gevent.spawn_later(10, lambda: 5)
with expected_time(SMALL):
result = gevent.wait(timeout=SMALL)
assert result is False, repr(result)
assert not x.dead, (x, x._start_event)
x.kill()
with no_time():
result = gevent.wait()
assert result is True
# exiting because of event (the spawned greenlet still runs)
for _ in xrange(2):
x = gevent.spawn_later(10, lambda: 5)
event = Event()
event_set = gevent.spawn_later(SMALL, event.set)
with expected_time(SMALL):
result = gevent.wait([event])
assert result == [event], repr(result)
assert not x.dead, x
assert event_set.dead
assert event.is_set()
x.kill()
with no_time():
result = gevent.wait()
assert result is True
# checking "ref=False" argument
for _ in xrange(2):
gevent.get_hub().loop.timer(10, ref=False).start(lambda: None)
with no_time():
result = gevent.wait()
assert result is True
# checking "ref=False" attribute
for _d in xrange(2):
w = gevent.get_hub().loop.timer(10)
w.start(lambda: None)
w.ref = False
with no_time():
result = gevent.wait()
assert result is True
import sys
if sys.version_info[0] == 2:
import threading
import gevent.monkey
gevent.monkey.patch_all()
import gevent
assert threading._sleep is gevent.sleep, threading._sleep
# testrunner timeout: 300
import sys
import glob
import subprocess
import time
TIMEOUT = 30
def kill(popen):
if popen.poll() is not None:
return
try:
popen.kill()
except OSError as ex:
if ex.errno == 3: # No such process
return
if ex.errno == 13: # Permission denied (translated from windows error 5: "Access is denied")
return
raise
def wait(popen):
end = time.time() + TIMEOUT
while popen.poll() is None:
if time.time() > end:
kill(popen)
popen.wait()
return 'TIMEOUT'
time.sleep(0.1)
return popen.poll()
def system(command):
popen = subprocess.Popen(command, shell=False)
try:
return wait(popen)
finally:
kill(popen)
modules = set()
for path in glob.glob('bench_*.py'):
modules.add(path)
if __name__ == '__main__':
assert modules
errors = []
for path in modules:
sys.stderr.write(path + '\n')
sys.stdout.flush()
command = [sys.executable, '-u', path, 'all']
res = system(command)
if res:
error = '%r failed with %s' % (' '.join(command), res)
sys.stderr.write(error + '\n')
errors.append(error)
sys.stderr.write('-----\n\n')
if errors:
sys.exit('\n'.join(errors))
from gevent.select import select
from gevent.server import StreamServer
from gevent import socket
def handler(socket, address):
while True:
if not socket.recv(1000):
break
server = StreamServer(('127.0.0.1', 0), handler)
server.start()
s = socket.create_connection(('127.0.0.1', server.server_port))
while True:
select([], [s.fileno()] * 10, [])
import unittest
from gevent import socket
import gevent
import errno
import os
from test__server import SimpleStreamServer
class Test(unittest.TestCase):
ServerSubClass = SimpleStreamServer
def makefile(self, timeout=0.1, bufsize=1):
sock = socket.create_connection((self.server.server_host, self.server.server_port))
sock.settimeout(timeout)
return sock.makefile(bufsize=bufsize)
def assertConnectionRefused(self):
try:
conn = self.makefile()
raise AssertionError('Connection was not refused: %r' % (conn._sock, ))
except socket.error as ex:
if ex.args[0] != errno.ECONNREFUSED:
raise
def assertRequestSucceeded(self):
conn = self.makefile()
conn.write('GET /ping HTTP/1.0\r\n\r\n')
result = conn.read()
assert result.endswith('\r\n\r\nPONG'), repr(result)
def init_server(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server.start()
gevent.sleep(0.01)
def test_socket_shutdown(self):
self.init_server()
self.server.socket.shutdown(socket.SHUT_RDWR)
self.assertConnectionRefused()
assert not self.server.started, self.server
def test_socket_close(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server.start()
self.server.socket.close()
self.assertConnectionRefused()
#assert not self.server.started
def test_socket_close_fileno(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server.start()
os.close(self.server.socket.fileno())
self.assertConnectionRefused()
#assert not self.server.started
def test_socket_file(self):
self.server = self.ServerSubClass(('127.0.0.1', 0))
self.server.start()
os.close(self.server.socket.fileno())
f = open("/dev/zero", "r")
self.assertConnectionRefused()
del f
if __name__ == '__main__':
unittest.main()
"""This is the extract from test_signal.py that runs forever until it fails.
It reproduces the bug where SIGCHLD either not delivered or somehow lost and thus
if libev does not poll waitpid() periodically, popen.wait() blocks forever.
The patch that fixes it: https://bitbucket.org/denis/gevent/changeset/adb8b5ac698c
Comment out the lines in ev.c that start the timer if you want to see for yourself.
Reproduced on my machine (Linux 3.0.0-16-generic) with backend epoll and select.
With signalfd enabled (GEVENT_BACKEND=signalfd) it seems to work.
"""
from __future__ import print_function
import gevent
from contextlib import closing
import gc
import pickle
from gevent import select
from gevent import subprocess
import traceback
import sys
import os
gc.disable()
MAX_DURATION = 10
def run_test():
child = subprocess.Popen(['/bin/true'])
child.wait() # << this is where it blocks
def test_main():
# This function spawns a child process to insulate the main
# test-running process from all the signals. It then
# communicates with that child process over a pipe and
# re-raises information about any exceptions the child
# throws. The real work happens in self.run_test().
os_done_r, os_done_w = os.pipe()
with closing(os.fdopen(os_done_r)) as done_r:
with closing(os.fdopen(os_done_w, 'w')) as done_w:
child = gevent.fork()
if not child:
# In the child process; run the test and report results
# through the pipe.
try:
done_r.close()
# Have to close done_w again here because
# exit_subprocess() will skip the enclosing with block.
with closing(done_w):
try:
run_test()
except:
pickle.dump(traceback.format_exc(), done_w)
else:
pickle.dump(None, done_w)
except:
print('Uh oh, raised from pickle.')
traceback.print_exc()
finally:
os._exit(0)
done_w.close()
# Block for up to MAX_DURATION seconds for the test to finish.
r, w, x = select.select([done_r], [], [], MAX_DURATION)
if done_r in r:
tb = pickle.load(done_r)
assert not tb, tb
else:
os.kill(child, 9)
assert False, 'Test deadlocked after %d seconds.' % MAX_DURATION
if __name__ == "__main__":
print(gevent.get_hub())
while True:
test_main()
sys.stderr.write('.')
import sys
import os
if os.system("ack 'from test import (?!test_support)|from test\.(?!test_support)' 2.5 2.6 2.7") != 256:
sys.exit('FAILED: Some tests in stdlib were not updated to not reference "test".')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment