From: Ben Darnell Date: Fri, 16 Dec 2022 19:56:39 +0000 (-0500) Subject: test: More lenient check for localhost resolver test X-Git-Tag: v6.3.0b1~19^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0105358212a4c4a1374b031b79a141efb734db47;p=thirdparty%2Ftornado.git test: More lenient check for localhost resolver test A recent update to pycares appears to have made it return only an ipv6 address for localhost. --- diff --git a/tornado/platform/caresresolver.py b/tornado/platform/caresresolver.py index 962f84f48..1ba45c9ac 100644 --- a/tornado/platform/caresresolver.py +++ b/tornado/platform/caresresolver.py @@ -15,14 +15,15 @@ if typing.TYPE_CHECKING: class CaresResolver(Resolver): """Name resolver based on the c-ares library. - 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 + 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``. + ``pycares`` will not return a mix of ``AF_INET`` and ``AF_INET6`` 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``. .. versionchanged:: 5.0 The ``io_loop`` argument (deprecated since version 4.1) has been removed. diff --git a/tornado/test/netutil_test.py b/tornado/test/netutil_test.py index 3911be6a2..df58e1f45 100644 --- a/tornado/test/netutil_test.py +++ b/tornado/test/netutil_test.py @@ -44,7 +44,14 @@ class _ResolverTestMixin(object): @gen_test def test_localhost(self: typing.Any): addrinfo = yield self.resolver.resolve("localhost", 80, socket.AF_UNSPEC) - self.assertIn((socket.AF_INET, ("127.0.0.1", 80)), addrinfo) + # Most of the time localhost resovles to either the ipv4 loopback + # address alone, or ipv4+ipv6. But some versions of pycares will only + # return the ipv6 version, so we have to check for either one alone. + self.assertTrue( + ((socket.AF_INET, ("127.0.0.1", 80)) in addrinfo) + or ((socket.AF_INET6, ("::1", 80)) in addrinfo), + f"loopback address not found in {addrinfo}", + ) # It is impossible to quickly and consistently generate an error in name diff --git a/tornado/test/tcpclient_test.py b/tornado/test/tcpclient_test.py index 2f7bdc104..ecfc82d6f 100644 --- a/tornado/test/tcpclient_test.py +++ b/tornado/test/tcpclient_test.py @@ -91,7 +91,11 @@ class TCPClientTest(AsyncTestCase): def do_test_connect(self, family, host, source_ip=None, source_port=None): port = self.start_server(family) stream = yield self.client.connect( - host, port, source_ip=source_ip, source_port=source_port + host, + port, + source_ip=source_ip, + source_port=source_port, + af=family, ) assert self.server is not None server_stream = yield self.server.queue.get() diff --git a/tornado/test/testing_test.py b/tornado/test/testing_test.py index ef47e97c2..ca48d567a 100644 --- a/tornado/test/testing_test.py +++ b/tornado/test/testing_test.py @@ -109,7 +109,7 @@ class AsyncHTTPTestCaseTest(AsyncHTTPTestCase): def test_fetch_full_http_url(self): # Ensure that self.fetch() recognizes absolute urls and does # not transform them into references to our main test server. - path = "http://localhost:%d/path" % self.second_port + path = "http://127.0.0.1:%d/path" % self.second_port response = self.fetch(path) self.assertEqual(response.request.url, path) diff --git a/tornado/test/websocket_test.py b/tornado/test/websocket_test.py index 442b3208d..f90c5f2c0 100644 --- a/tornado/test/websocket_test.py +++ b/tornado/test/websocket_test.py @@ -1,5 +1,6 @@ import asyncio import functools +import socket import traceback import typing import unittest @@ -9,6 +10,7 @@ from tornado import gen from tornado.httpclient import HTTPError, HTTPRequest from tornado.locks import Event from tornado.log import gen_log, app_log +from tornado.netutil import Resolver from tornado.simple_httpclient import SimpleAsyncHTTPClient from tornado.template import DictLoader from tornado.testing import AsyncHTTPTestCase, gen_test, bind_unused_port, ExpectLog @@ -539,6 +541,15 @@ class WebSocketTest(WebSocketBaseTestCase): def test_check_origin_invalid_subdomains(self): port = self.get_http_port() + # CaresResolver may return ipv6-only results for localhost, but our + # server is only running on ipv4. Test for this edge case and skip + # the test if it happens. + addrinfo = yield Resolver().resolve("localhost", port) + families = set(addr[0] for addr in addrinfo) + if socket.AF_INET not in families: + self.skipTest("localhost does not resolve to ipv4") + return + url = "ws://localhost:%d/echo" % port # Subdomains should be disallowed by default. If we could pass a # resolver to websocket_connect we could test sibling domains as well.