Commit e89c02a3 authored by Denis Bilenko's avatar Denis Bilenko

Update DNS tests

- extract IPv6-related tests from test__socket_dns.py and put them into test__socket_dns6.py
- improve log messages
parent 98fa36ca
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# testrunner timeout: 300
from __future__ import with_statement from __future__ import with_statement
import sys import sys
import re import re
import traceback
import greentest import greentest
import socket import socket
from time import time from time import time
...@@ -12,13 +10,10 @@ import gevent ...@@ -12,13 +10,10 @@ import gevent
import gevent.socket as gevent_socket import gevent.socket as gevent_socket
from util import log from util import log
RAISE_TOO_SLOW = False
# also test: '<broadcast>'
resolver = gevent.get_hub().resolver resolver = gevent.get_hub().resolver
log('Resolver: %s', resolver) log('Resolver: %s', resolver)
if getattr(resolver, 'pool', None) is not None: if getattr(resolver, 'pool', None) is not None:
resolver.pool.size = 1 resolver.pool.size = 1
...@@ -27,23 +22,6 @@ assert gevent_socket.gaierror is socket.gaierror ...@@ -27,23 +22,6 @@ assert gevent_socket.gaierror is socket.gaierror
assert gevent_socket.error is socket.error assert gevent_socket.error is socket.error
VERBOSE = sys.argv.count('-v') + 2 * sys.argv.count('-vv') VERBOSE = sys.argv.count('-v') + 2 * sys.argv.count('-vv')
PASS = True
LOGFILE = sys.stderr
def log(s, *args, **kwargs):
newline = kwargs.pop('newline', True)
assert not kwargs, kwargs
if not VERBOSE:
return
try:
s = s % args
except Exception:
traceback.print_exc()
s = '%s %r' % (s, args)
if newline:
s += '\n'
LOGFILE.write(s)
def _run(function, *args): def _run(function, *args):
...@@ -55,27 +33,28 @@ def _run(function, *args): ...@@ -55,27 +33,28 @@ def _run(function, *args):
return sys.exc_info()[1] return sys.exc_info()[1]
def log_fcall(function, args): def format_call(function, args):
args = repr(args) args = repr(args)
if args.endswith(',)'): if args.endswith(',)'):
args = args[:-2] + ')' args = args[:-2] + ')'
log('\n%7s.%s%s', try:
function.__module__.replace('gevent.socket', 'gevent'), module = function.__module__.replace('gevent.socket', 'gevent').replace('_socket', 'stdlib')
function.__name__, name = function.__name__
args, return '%s:%s%s' % (module, name, args)
newline=False) except AttributeError:
return function + args
def log_fresult(result, seconds): def log_fresult(result, seconds):
if isinstance(result, Exception): if isinstance(result, Exception):
log(' -> raised %r (%.3f)', result, seconds * 1000.0) log(' -=> raised %r %.2fms', result, seconds * 1000.0)
else: else:
log(' -> returned %r (%.3f)', result, seconds * 1000.0) log(' -=> returned %r %.2fms', result, seconds * 1000.0)
def run(function, *args): def run(function, *args):
if VERBOSE >= 2: if VERBOSE >= 2:
log_fcall(function, args) log(format_call(function, args))
delta = time() delta = time()
result = _run(function, *args) result = _run(function, *args)
delta = time() - delta delta = time() - delta
...@@ -85,7 +64,7 @@ def run(function, *args): ...@@ -85,7 +64,7 @@ def run(function, *args):
def log_call(result, time, function, *args): def log_call(result, time, function, *args):
log_fcall(function, args) log(format_call(function, args))
log_fresult(result, time) log_fresult(result, time)
...@@ -106,6 +85,13 @@ def compare_ipv6(a, b): ...@@ -106,6 +85,13 @@ def compare_ipv6(a, b):
return a == b return a == b
def contains_5tuples(lst):
for item in lst:
if not (isinstance(item, tuple) and len(item) == 5):
return False
return True
def relaxed_is_equal(a, b): def relaxed_is_equal(a, b):
""" """
>>> relaxed_is_equal([(10, 1, 6, '', ('2a00:1450:400f:801::1010', 80, 0, 0))], [(10, 1, 6, '', ('2a00:1450:400f:800::1011', 80, 0, 0))]) >>> relaxed_is_equal([(10, 1, 6, '', ('2a00:1450:400f:801::1010', 80, 0, 0))], [(10, 1, 6, '', ('2a00:1450:400f:800::1011', 80, 0, 0))])
...@@ -122,6 +108,10 @@ def relaxed_is_equal(a, b): ...@@ -122,6 +108,10 @@ def relaxed_is_equal(a, b):
if hasattr(a, '__iter__'): if hasattr(a, '__iter__'):
if len(a) != len(b): if len(a) != len(b):
return False return False
if contains_5tuples(a) and contains_5tuples(b):
# getaddrinfo results
a = sorted(a)
b = sorted(b)
return all(relaxed_is_equal(x, y) for (x, y) in zip(a, b)) return all(relaxed_is_equal(x, y) for (x, y) in zip(a, b))
return a == b return a == b
...@@ -170,63 +160,37 @@ def add(klass, hostname, name=None): ...@@ -170,63 +160,37 @@ def add(klass, hostname, name=None):
setattr(klass, test5.__name__, test5) setattr(klass, test5.__name__, test5)
class TooSlow(AssertionError):
pass
class TestCase(greentest.TestCase): class TestCase(greentest.TestCase):
__timeout__ = 60 __timeout__ = 30
switch_expected = None switch_expected = None
def _test_once(self, func, *args): def _test(self, func, *args):
if VERBOSE:
log('')
gevent_func = getattr(gevent_socket, func) gevent_func = getattr(gevent_socket, func)
real_func = getattr(socket, func) real_func = getattr(socket, func)
real_result, time_real = run(real_func, *args) real_result, time_real = run(real_func, *args)
result, time_gevent = run(gevent_func, *args) gevent_result, time_gevent = run(gevent_func, *args)
if VERBOSE == 1 and repr(result) != repr(real_result): if VERBOSE == 1 and repr(gevent_result) != repr(real_result):
# slightly less verbose mode: only print the results that are different # slightly less verbose mode: only print the results that are different
log_call(result, time_gevent, gevent_func, *args)
log_call(real_result, time_real, real_func, *args) log_call(real_result, time_real, real_func, *args)
log('') log_call(gevent_result, time_gevent, gevent_func, *args)
elif VERBOSE >= 2: self.assertEqualResults(real_result, gevent_result, func, args)
log('')
self.assertEqualResults(real_result, result, func)
if isinstance(real_result, Exception):
if isinstance(result, Exception):
# built-in socket module is faster at raising exceptions
allowed = 2.
else:
# built-in socket module raised an error, gevent made a real query
allowed = 100000.
else:
allowed = 1.2
if time_gevent / allowed > time_real and (time_gevent + time_real) > 0.0005:
# QQQ use clock() on windows
times = None
if not time_real:
if time_gevent:
times = time_gevent / 0.001
else:
times = 1
if times is None:
times = time_gevent / time_real
params = (func, args, times, time_gevent * 1000.0, time_real * 1000.0)
raise TooSlow('gevent_socket.%s%s is %.1f times slower (%.3fms versus %.3fms)' % params)
return result
def _test(self, func, *args): if time_gevent > time_real + 0.01 and time_gevent > 0.02:
try: msg = 'gevent:%s%s took %dms versus %dms stdlib' % (func, args, time_gevent * 1000.0, time_real * 1000.0)
return self._test_once(func, *args)
except TooSlow, ex: if time_gevent > time_real + 1:
if RAISE_TOO_SLOW: word = 'VERY'
raise
else: else:
if not VERBOSE: word = 'quite'
log('')
log('WARNING: %s', ex)
def assertEqualResults(self, real_result, gevent_result, func): log('\nWARNING: %s slow: %s', word, msg)
return gevent_result
def assertEqualResults(self, real_result, gevent_result, func, args):
errors = [socket.gaierror, socket.herror, TypeError] errors = [socket.gaierror, socket.herror, TypeError]
if type(real_result) in errors and type(gevent_result) in errors: if type(real_result) in errors and type(gevent_result) in errors:
if type(real_result) is not type(gevent_result): if type(real_result) is not type(gevent_result):
...@@ -238,7 +202,7 @@ class TestCase(greentest.TestCase): ...@@ -238,7 +202,7 @@ class TestCase(greentest.TestCase):
return return
if relaxed_is_equal(gevent_result, real_result): if relaxed_is_equal(gevent_result, real_result):
return return
raise AssertionError('%r != %r' % (gevent_result, real_result)) raise AssertionError('%r != %r\n %s' % (gevent_result, real_result, format_call(func, args)))
class TestTypeError(TestCase): class TestTypeError(TestCase):
...@@ -282,10 +246,11 @@ class Test127001(TestCase): ...@@ -282,10 +246,11 @@ class Test127001(TestCase):
add(Test127001, '127.0.0.1') add(Test127001, '127.0.0.1')
# class TestBroadcast(TestCase): class TestBroadcast(TestCase):
# switch_expected = False switch_expected = False
#
# add(TestBroadcast, '<broadcast>')
add(TestBroadcast, '<broadcast>')
class TestEtcHosts(TestCase): class TestEtcHosts(TestCase):
...@@ -409,39 +374,6 @@ class TestInterrupted_gethostbyname(greentest.GenericWaitTestCase): ...@@ -409,39 +374,6 @@ class TestInterrupted_gethostbyname(greentest.GenericWaitTestCase):
# pass # pass
class Test6(TestCase):
pass
# host that only has AAAA record
host = 'aaaa.test-ipv6.com'
def test_empty(self):
self._test('getaddrinfo', self.host, 'http')
def test_inet(self):
self._test('getaddrinfo', self.host, None, socket.AF_INET)
def test_inet6(self):
self._test('getaddrinfo', self.host, None, socket.AF_INET6)
def test_unspec(self):
self._test('getaddrinfo', self.host, None, socket.AF_UNSPEC)
class Test6_google(Test6):
host = 'ipv6.google.com'
class Test6_ds(Test6):
# host that has both A and AAAA records
host = 'ds.test-ipv6.com'
add(Test6, Test6.host)
add(Test6_google, Test6_google.host)
add(Test6_ds, Test6_ds.host)
class TestBadName(TestCase): class TestBadName(TestCase):
pass pass
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import with_statement
import greentest
import socket
from test__socket_dns import TestCase, add
class Test6(TestCase):
# host that only has AAAA record
host = 'aaaa.test-ipv6.com'
def test_empty(self):
self._test('getaddrinfo', self.host, 'http')
def test_inet(self):
self._test('getaddrinfo', self.host, None, socket.AF_INET)
def test_inet6(self):
self._test('getaddrinfo', self.host, None, socket.AF_INET6)
def test_unspec(self):
self._test('getaddrinfo', self.host, None, socket.AF_UNSPEC)
class Test6_google(Test6):
host = 'ipv6.google.com'
class Test6_ds(Test6):
# host that has both A and AAAA records
host = 'ds.test-ipv6.com'
add(Test6, Test6.host)
add(Test6_google, Test6_google.host)
add(Test6_ds, Test6_ds.host)
if __name__ == '__main__':
greentest.main()
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