From: Ben Darnell Date: Sun, 24 Feb 2013 17:43:06 +0000 (-0500) Subject: Add a resolver test script for external queries that cannot be unittested. X-Git-Tag: v3.0.0~91 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d735bd818ae92a54504f42c66c487b0556d5d6dc;p=thirdparty%2Ftornado.git Add a resolver test script for external queries that cannot be unittested. Note an issue with CaresResolver (it cannot resolve www.dropbox.com when family==AF_UNSPEC) --- diff --git a/maint/requirements.txt b/maint/requirements.txt index a8875bf78..c41816019 100644 --- a/maint/requirements.txt +++ b/maint/requirements.txt @@ -4,6 +4,7 @@ Twisted==12.2.0 futures==2.1.3 mock==1.0.1 +pycares==0.4.0 pycurl==7.19.0 # Other useful tools diff --git a/maint/scripts/test_resolvers.py b/maint/scripts/test_resolvers.py new file mode 100644 index 000000000..6cfe15d72 --- /dev/null +++ b/maint/scripts/test_resolvers.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +from __future__ import print_function + +import pprint +import socket + +from tornado import gen +from tornado.ioloop import IOLoop +from tornado.netutil import Resolver, ThreadedResolver +from tornado.options import parse_command_line, define, options + +try: + import twisted +except ImportError: + twisted = None + +try: + import pycares +except ImportError: + pycares = None + +define('family', default='unspec', + help='Address family to query: unspec, inet, or inet6') + +@gen.engine +def main(): + args = parse_command_line() + + if not args: + args = ['localhost', 'www.google.com', + 'www.facebook.com', 'www.dropbox.com'] + + resolvers = [Resolver(), ThreadedResolver()] + + if twisted is not None: + from tornado.platform.twisted import TwistedResolver + resolvers.append(TwistedResolver()) + + if pycares is not None: + from tornado.platform.caresresolver import CaresResolver + resolvers.append(CaresResolver()) + + family = { + 'unspec': socket.AF_UNSPEC, + 'inet': socket.AF_INET, + 'inet6': socket.AF_INET6, + }[options.family] + + for host in args: + print('Resolving %s' % host) + for resolver in resolvers: + addrinfo = yield resolver.getaddrinfo(host, 80, family) + print('%s: %s' % (resolver.__class__.__name__, + pprint.pformat(addrinfo))) + print() + IOLoop.instance().stop() + +if __name__ == '__main__': + IOLoop.instance().add_callback(main) + IOLoop.instance().start() diff --git a/tornado/platform/caresresolver.py b/tornado/platform/caresresolver.py index 11dafd4a2..fe8cc377c 100644 --- a/tornado/platform/caresresolver.py +++ b/tornado/platform/caresresolver.py @@ -12,6 +12,11 @@ class CaresResolver(Resolver): This is a non-blocking and non-threaded resolver. It may not produce the same results as the system resolver, but can be used for non-blocking resolution when threads cannot be used. + + c-ares fails to resolve some names when ``family`` is ``AF_UNSPEC``, + so it is only recommended for use in ``AF_INET`` (i.e. IPv4). This is + the default for `tornado.simple_httpclient`, but other libraries + may default to ``AF_UNSPEC``. """ def initialize(self, io_loop=None): self.io_loop = io_loop or IOLoop.instance() diff --git a/tornado/platform/twisted.py b/tornado/platform/twisted.py index f5b042da1..419b98832 100644 --- a/tornado/platform/twisted.py +++ b/tornado/platform/twisted.py @@ -500,8 +500,8 @@ class TwistedResolver(Resolver): are ignored. It may fail to resolve when ``family`` is not ``socket.AF_UNSPEC``. """ - def initialize(self, io_loop): - self.io_loop = io_loop + def initialize(self, io_loop=None): + self.io_loop = io_loop or IOLoop.instance() # partial copy of twisted.names.client.createResolver, which doesn't # allow for a reactor to be passed in. self.reactor = tornado.platform.twisted.TornadoReactor(io_loop)