예제 #1
0
    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
예제 #3
0
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
예제 #4
0
 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
예제 #5
0
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)
예제 #6
0
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')
예제 #7
0
 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')
예제 #8
0
    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
예제 #9
0
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
예제 #10
0
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()
예제 #12
0
def log_call(result, runtime, function, *args):
    log(format_call(function, args))
    log_fresult(result, runtime)
예제 #13
0
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'

예제 #14
0
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)
예제 #15
0
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()
예제 #16
0
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)