def assertEqualResults(self, real_result, gevent_result, func): errors = (socket.gaierror, socket.herror, TypeError) if isinstance(real_result, errors) and isinstance( gevent_result, errors): if type(real_result) is not type(gevent_result): log('WARNING: error type mismatch: %r (gevent) != %r (stdlib)', gevent_result, real_result) return real_result = self._normalize_result(real_result, func) gevent_result = self._normalize_result(gevent_result, func) real_result_repr = repr(real_result) gevent_result_repr = repr(gevent_result) if real_result_repr == gevent_result_repr: return if relaxed_is_equal(gevent_result, real_result): return # 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)): return # From 2.7 on, assertEqual does a better job highlighting the results than we would # because it calls assertSequenceEqual, which highlights the exact # difference in the tuple self.assertEqual(real_result, gevent_result)
def _test(self, func_name, *args): """ Runs the function *func_name* with *args* and compares gevent and the system. Returns the gevent result. """ gevent_func = getattr(gevent_socket, func_name) real_func = monkey.get_original('socket', func_name) tester = getattr(self, '_run_test_' + func_name, self._run_test_generic) result = tester(func_name, real_func, gevent_func, args) _real_result, time_real, gevent_result, time_gevent = result if self.verbose_dns and time_gevent > time_real + 0.02 and time_gevent > 0.03: msg = 'gevent:%s%s took %dms versus %dms stdlib' % ( func_name, args, time_gevent * 1000.0, time_real * 1000.0) if time_gevent > time_real + 1: word = 'VERY' else: word = 'quite' util.log('\nWARNING: %s slow: %s', word, msg, color='warning') return gevent_result
def run(function, *args): if DEBUG: log(format_call(function, args)) delta = time() result = _run(function, *args) delta = time() - delta if DEBUG: log_fresult(result, delta) return result, delta
def _run_test_generic(self, func_name, real_func, gevent_func, func_args): real_result, time_real = self.run_resolver(real_func, func_args) gevent_result, time_gevent = self.run_resolver(gevent_func, func_args) if util.QUIET and self.should_log_results(real_result, gevent_result): util.log('') self.__trace_call(real_result, time_real, real_func, func_args) self.__trace_call(gevent_result, time_gevent, gevent_func, func_args) self.assertEqualResults(real_result, gevent_result, func_name) return real_result, time_real, gevent_result, time_gevent
def log_fresult(result, seconds): if isinstance(result, Exception): msg = ' -=> raised %r' % (result, ) else: msg = ' -=> returned %r' % (result, ) time_ms = ' %.2fms' % (seconds * 1000.0, ) space = 80 - len(msg) - len(time_ms) if space > 0: space = ' ' * space else: space = '' log(msg + space + time_ms)
def dnspython_lenient_compare_exceptions(self, real_result, gevent_result, func_name): try: TestCase._compare_exceptions(self, real_result, gevent_result, func_name) except AssertionError: # Allow gethostbyaddr to raise different things in a few rare cases. if (func_name != 'gethostbyaddr' or type(real_result) not in (socket.herror, socket.gaierror) or type(gevent_result) not in (socket.herror, socket.gaierror)): raise util.log( 'WARNING: error type mismatch for %s: %r (gevent) != %r (stdlib)', func_name, gevent_result, real_result, color='warning')
def _compare_exceptions_lenient(self, real_result, gevent_result, func_name): try: self._compare_exceptions_strict(real_result, gevent_result, func_name) except AssertionError: # Allow raising different things in a few rare cases. if ( func_name not in ( 'getaddrinfo', 'gethostbyaddr', 'gethostbyname', 'gethostbyname_ex', 'getnameinfo', ) or type(real_result) not in (socket.herror, socket.gaierror) or type(gevent_result) not in (socket.herror, socket.gaierror, socket.error) ): raise util.log('WARNING: error type mismatch for %s: %r (gevent) != %r (stdlib)', func_name, gevent_result, real_result, color='warning')
def _test(self, func, *args): gevent_func = getattr(gevent_socket, func) real_func = monkey.get_original('socket', func) real_result, time_real = run(real_func, *args) gevent_result, time_gevent = run(gevent_func, *args) if not DEBUG and self.should_log_results(real_result, gevent_result): log('') log_call(real_result, time_real, real_func, *args) log_call(gevent_result, time_gevent, gevent_func, *args) self.assertEqualResults(real_result, gevent_result, func) if self.verbose_dns and time_gevent > time_real + 0.01 and time_gevent > 0.02: msg = 'gevent:%s%s took %dms versus %dms stdlib' % (func, args, time_gevent * 1000.0, time_real * 1000.0) if time_gevent > time_real + 1: word = 'VERY' else: word = 'quite' log('\nWARNING: %s slow: %s', word, msg) return gevent_result
def _build_test_classes(): result = {} try: example_dir = util.ExampleMixin().cwd except unittest.SkipTest: util.log("WARNING: No examples dir found", color='suboptimal-behaviour') return result ignore = _find_files_to_ignore() for filename in glob.glob(example_dir + '/*.py'): bn = os.path.basename(filename) if bn in ignore: continue tc = type( 'Test_' + bn, (_AbstractTestMixin, greentest.TestCase), { 'filename': bn, 'time_range': time_ranges.get(bn, _AbstractTestMixin.time_range) }) result[tc.__name__] = tc return result
def TESTRUNNER(tests=None): if not os.path.exists(directory): util.log('WARNING: No test directory found at %s', directory) return with open(os.path.join(directory, 'version')) as f: preferred_version = f.read().strip() if preferred_version != version: util.log('WARNING: The tests in %s/ are from version %s and your Python is %s', directory, preferred_version, version) version_tests = glob.glob('%s/test_*.py' % full_directory) version_tests = sorted(version_tests) if not tests: tests = glob.glob('%s/test_*.py' % directory) tests = sorted(tests) PYTHONPATH = (os.getcwd() + os.pathsep + get_absolute_pythonpath()).rstrip(':') tests = [os.path.basename(x) for x in tests] version_tests = [os.path.basename(x) for x in version_tests] options = { 'cwd': directory, 'timeout': TIMEOUT, 'setenv': { 'PYTHONPATH': PYTHONPATH, # debug produces resource tracking warnings for the # CFFI backends. On Python 2, many of the stdlib tests # rely on refcounting to close sockets so they produce # lots of noise. Python 3 is not completely immune; # test_ftplib.py tends to produce warnings---and the Python 3 # test framework turns those into test failures! 'GEVENT_DEBUG': 'error', } } if tests and not sys.platform.startswith("win"): atexit.register(os.system, 'rm -f */@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) continue yield basic_args + [filename], options.copy() options['cwd'] = full_directory for filename in version_tests: yield basic_args + [filename], options.copy()
def TESTRUNNER(tests=None): if not is_resource_enabled('gevent_monkey'): util.log('WARNING: Testing monkey-patched stdlib has been disabled', color="suboptimal-behaviour") return try: test_dir, version_test_dir = util.find_stdlib_tests() except util.NoSetupPyFound as e: util.log("WARNING: No setup.py and src/greentest found: %r", e, color="suboptimal-behaviour") return if not os.path.exists(test_dir): util.log('WARNING: No test directory found at %s', test_dir, color="suboptimal-behaviour") return with open(os.path.join(test_dir, 'version')) as f: preferred_version = f.read().strip() running_version = sysinfo.get_python_version() if preferred_version != running_version: util.log( 'WARNING: The tests in %s/ are from version %s and your Python is %s', test_dir, preferred_version, running_version, color="suboptimal-behaviour") version_tests = glob.glob('%s/test_*.py' % version_test_dir) version_tests = sorted(version_tests) if not tests: tests = glob.glob('%s/test_*.py' % test_dir) tests = sorted(tests) PYTHONPATH = (os.getcwd() + os.pathsep + get_absolute_pythonpath()).rstrip(':') tests = [os.path.basename(x) for x in tests] version_tests = [os.path.basename(x) for x in version_tests] options = { 'cwd': test_dir, 'timeout': TIMEOUT, 'setenv': { 'PYTHONPATH': PYTHONPATH, # debug produces resource tracking warnings for the # CFFI backends. On Python 2, many of the stdlib tests # rely on refcounting to close sockets so they produce # lots of noise. Python 3 is not completely immune; # test_ftplib.py tends to produce warnings---and the Python 3 # test framework turns those into test failures! 'GEVENT_DEBUG': 'error', } } if tests and not sys.platform.startswith("win"): atexit.register(os.system, 'rm -f */@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, test_dir, version_test_dir) continue yield basic_args + [filename], options.copy() options['cwd'] = version_test_dir for filename in version_tests: yield basic_args + [filename], options.copy()
def log_call(result, runtime, function, *args): log(format_call(function, args)) log_fresult(result, runtime)
from gevent import monkey import os import re import gevent.testing as greentest import unittest import socket from time import time import traceback import gevent.socket as gevent_socket from gevent.testing.util import log from gevent.testing import six from gevent.testing.six import xrange resolver = gevent.get_hub().resolver log('Resolver: %s', resolver) if getattr(resolver, 'pool', None) is not None: resolver.pool.size = 1 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 assert gevent_socket.error is socket.error DEBUG = os.getenv('GEVENT_DEBUG', '') == 'trace'
def main(): # pylint:disable=too-many-locals cwd = os.getcwd() # Use pure_python to get the correct module source and docstrings os.environ['PURE_PYTHON'] = '1' import gevent from gevent import socket from gevent.testing import util from gevent.testing import sysinfo if sysinfo.WIN: FORBIDDEN_MODULES.update({ # Uses commands only found on posix 'gevent.subprocess', }) try: allowed_modules = sys.argv[1:] sys.path.append('.') globs = { 'myfunction': myfunction, 'gevent': gevent, 'socket': socket, } modules = Modules(allowed_modules) if not modules: sys.exit('No modules found matching %s' % ' '.join(allowed_modules)) suite = unittest.TestSuite() checker = RENormalizingOutputChecker(( # Normalize subprocess.py: BSD ls is in the example, gnu ls outputs # 'cannot access' (re.compile( "ls: cannot access 'non_existent_file': No such file or directory" ), "ls: non_existent_file: No such file or directory"), # Python 3 bytes add a "b". (re.compile(r'b(".*?")'), r"\1"), (re.compile(r"b('.*?')"), r"\1"), )) tests_count = 0 modules_count = 0 for m, path in sorted(modules): with open(path, 'rb') as f: contents = f.read() if re.search(br'^\s*>>> ', contents, re.M): s = doctest.DocTestSuite(m, extraglobs=globs, checker=checker) test_count = len(s._tests) util.log('%s (from %s): %s tests', m, path, test_count) suite.addTest(s) modules_count += 1 tests_count += test_count util.log('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)
def TESTRUNNER(tests=None): try: test_dir, version_test_dir = find_stdlib_tests() except util.NoSetupPyFound as e: util.log("WARNING: No setup.py and src/greentest found: %r", e, color="suboptimal-behaviour") return if not os.path.exists(test_dir): util.log('WARNING: No test directory found at %s', test_dir, color="suboptimal-behaviour") return with open(os.path.join(test_dir, 'version')) as f: preferred_version = f.read().strip() running_version = get_python_version() if preferred_version != running_version: util.log('WARNING: The tests in %s/ are from version %s and your Python is %s', test_dir, preferred_version, running_version, color="suboptimal-behaviour") version_tests = glob.glob('%s/test_*.py' % version_test_dir) version_tests = sorted(version_tests) if not tests: tests = glob.glob('%s/test_*.py' % test_dir) tests = sorted(tests) PYTHONPATH = (os.getcwd() + os.pathsep + get_absolute_pythonpath()).rstrip(':') tests = [os.path.basename(x) for x in tests] version_tests = [os.path.basename(x) for x in version_tests] options = { 'cwd': test_dir, 'timeout': TIMEOUT, 'setenv': { 'PYTHONPATH': PYTHONPATH, # debug produces resource tracking warnings for the # CFFI backends. On Python 2, many of the stdlib tests # rely on refcounting to close sockets so they produce # lots of noise. Python 3 is not completely immune; # test_ftplib.py tends to produce warnings---and the Python 3 # test framework turns those into test failures! 'GEVENT_DEBUG': 'error', } } if tests and not sys.platform.startswith("win"): atexit.register(os.system, 'rm -f */@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, test_dir, version_test_dir) continue yield basic_args + [filename], options.copy() options['cwd'] = version_test_dir for filename in version_tests: yield basic_args + [filename], options.copy()
def main(): # pylint:disable=too-many-locals cwd = os.getcwd() # Use pure_python to get the correct module source and docstrings os.environ['PURE_PYTHON'] = '1' import gevent from gevent import socket from gevent.testing import util from gevent.testing import sysinfo if sysinfo.WIN: FORBIDDEN_MODULES.update({ # Uses commands only found on posix 'gevent.subprocess', }) try: allowed_modules = sys.argv[1:] sys.path.append('.') globs = { 'myfunction': myfunction, 'gevent': gevent, 'socket': socket, } modules = Modules(allowed_modules) if not modules: sys.exit('No modules found matching %s' % ' '.join(allowed_modules)) suite = unittest.TestSuite() checker = RENormalizingOutputChecker(( # Normalize subprocess.py: BSD ls is in the example, gnu ls outputs # 'cannot access' (re.compile( "ls: cannot access 'non_existent_file': No such file or directory"), "ls: non_existent_file: No such file or directory"), # Python 3 bytes add a "b". (re.compile(r'b(".*?")'), r"\1"), (re.compile(r"b('.*?')"), r"\1"), )) tests_count = 0 modules_count = 0 for m, path in sorted(modules): with open(path, 'rb') as f: contents = f.read() if re.search(br'^\s*>>> ', contents, re.M): s = doctest.DocTestSuite(m, extraglobs=globs, checker=checker) test_count = len(s._tests) util.log('%s (from %s): %s tests', m, path, test_count) suite.addTest(s) modules_count += 1 tests_count += test_count util.log('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)