Source: dnspython Version: 2.2.1-1 Severity: normal Tags: patch X-Debbugs-Cc: daniel.bung...@canonical.com
Dear Maintainer, During testing of dnspython on Ubuntu, we have found that the servers required for some of the tests may not be available, which could cause an autopkgtest failure. The Ubuntu bug for this can be found at: https://bugs.launchpad.net/ubuntu/+source/dnspython/+bug/1976565 I have prepared a patch, based on not-yet merged work by dnspython upstream. -Dan
diff -Nru dnspython-2.2.1/debian/changelog dnspython-2.2.1/debian/changelog --- dnspython-2.2.1/debian/changelog 2022-05-16 12:59:36.000000000 -0600 +++ dnspython-2.2.1/debian/changelog 2022-06-07 13:32:40.000000000 -0600 @@ -1,3 +1,10 @@ +dnspython (2.2.1-2) unstable; urgency=medium + + [Bob Halley] + * Update test suite to improve network checking (Closes: #FIXME) + + -- Dan Bungert <daniel.bung...@canonical.com> Tue, 07 Jun 2022 13:32:40 -0600 + dnspython (2.2.1-1) unstable; urgency=medium [ Benjamin Drung ] diff -Nru dnspython-2.2.1/debian/patches/0003-Improve-network-checking-812.patch dnspython-2.2.1/debian/patches/0003-Improve-network-checking-812.patch --- dnspython-2.2.1/debian/patches/0003-Improve-network-checking-812.patch 1969-12-31 17:00:00.000000000 -0700 +++ dnspython-2.2.1/debian/patches/0003-Improve-network-checking-812.patch 2022-06-07 13:32:40.000000000 -0600 @@ -0,0 +1,193 @@ +Description: Improve network checking [#812]. +Author: Bob Halley <hal...@dnspython.org> +Forwarded: not-needed +Last-Update: 2022-06-04 +--- + tests/test_doh.py | 19 +++----------- + tests/test_query.py | 16 ++++-------- + tests/test_resolver.py | 1 + + tests/util.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++---- + 4 files changed, 75 insertions(+), 31 deletions(-) + +diff --git a/tests/test_doh.py b/tests/test_doh.py +index fb41723..38e2ada 100644 +--- a/tests/test_doh.py ++++ b/tests/test_doh.py +@@ -37,31 +37,20 @@ if dns.query._have_httpx: + + import tests.util + +-# Probe for IPv4 and IPv6 + resolver_v4_addresses = [] + resolver_v6_addresses = [] +-try: +- with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: +- s.settimeout(4) +- s.connect(('8.8.8.8', 53)) ++if tests.util.have_ipv4(): + resolver_v4_addresses = [ + '1.1.1.1', + '8.8.8.8', + # '9.9.9.9', + ] +-except Exception: +- pass +-try: +- with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) as s: +- s.connect(('2001:4860:4860::8888', 53)) ++if tests.util.have_ipv6(): + resolver_v6_addresses = [ +- '2606:4700:4700::1111', +- # Google says 404 +- # '2001:4860:4860::8888', ++ "2606:4700:4700::1111", ++ "2001:4860:4860::8888", + # '2620:fe::fe', + ] +-except Exception: +- pass + + KNOWN_ANYCAST_DOH_RESOLVER_URLS = ['https://cloudflare-dns.com/dns-query', + 'https://dns.google/dns-query', +diff --git a/tests/test_query.py b/tests/test_query.py +index 6ffa694..1089fd0 100644 +--- a/tests/test_query.py ++++ b/tests/test_query.py +@@ -48,18 +48,12 @@ except ImportError: + class Server(object): + pass + +-# Probe for IPv4 and IPv6 ++ + query_addresses = [] +-for (af, address) in ((socket.AF_INET, '8.8.8.8'), +- (socket.AF_INET6, '2001:4860:4860::8888')): +- try: +- with socket.socket(af, socket.SOCK_DGRAM) as s: +- # Connecting a UDP socket is supposed to return ENETUNREACH if +- # no route to the network is present. +- s.connect((address, 53)) +- query_addresses.append(address) +- except Exception: +- pass ++if tests.util.have_ipv4(): ++ query_addresses.append("8.8.8.8") ++if tests.util.have_ipv6(): ++ query_addresses.append("2001:4860:4860::8888") + + keyring = dns.tsigkeyring.from_text({'name': 'tDz6cfXXGtNivRpQ98hr6A=='}) + +diff --git a/tests/test_resolver.py b/tests/test_resolver.py +index 36f1b7f..3f289c0 100644 +--- a/tests/test_resolver.py ++++ b/tests/test_resolver.py +@@ -667,6 +667,7 @@ class LiveResolverTests(unittest.TestCase): + self.assertIn(qname, nx.qnames()) + self.assertGreaterEqual(len(nx.responses()), 1) + ++ @unittest.skipIf(not tests.util.have_ipv4(), "IPv4 not reachable") + def testResolveCacheHit(self): + res = dns.resolver.Resolver(configure=False) + res.nameservers = ['8.8.8.8'] +diff --git a/tests/util.py b/tests/util.py +index c9aef6a..2461ab6 100644 +--- a/tests/util.py ++++ b/tests/util.py +@@ -20,32 +20,92 @@ import inspect + import os + import socket + ++import dns.message ++import dns.name ++import dns.query ++import dns.rdataclass ++import dns.rdatatype ++ + # Cache for is_internet_reachable() + _internet_reachable = None ++_have_ipv4 = False ++_have_ipv6 = False + + def here(filename): + return os.path.join(os.path.dirname(__file__), filename) + + ++def check_networking(addresses): ++ """Can we do a DNS resolution via UDP and TCP to at least one of the addresses?""" ++ for address in addresses: ++ try: ++ q = dns.message.make_query(dns.name.root, dns.rdatatype.NS) ++ ok = False ++ # We try UDP a few times in case we get unlucky and a packet is lost. ++ for i in range(5): ++ # We don't check the answer other than make sure there is one. ++ try: ++ r = dns.query.udp(q, address, timeout=4) ++ ns = r.find_rrset( ++ r.answer, dns.name.root, dns.rdataclass.IN, dns.rdatatype.NS ++ ) ++ ok = True ++ break ++ except Exception: ++ continue # UDP try loop ++ if not ok: ++ continue # addresses loop ++ try: ++ r = dns.query.tcp(q, address, timeout=4) ++ ns = r.find_rrset( ++ r.answer, dns.name.root, dns.rdataclass.IN, dns.rdatatype.NS ++ ) ++ # UDP and TCP both work! ++ return True ++ except Exception: ++ continue ++ except Exception as e: ++ pass ++ return False ++ ++ + def is_internet_reachable(): + """Check if the Internet is reachable. + + Setting the environment variable `NO_INTERNET` will let this + function always return False. The result is cached. ++ ++ We check using the Google and Cloudflare public resolvers as they are highly ++ available and have well-known stable addresses. + """ + global _internet_reachable + if _internet_reachable is None: + if os.environ.get("NO_INTERNET"): + _internet_reachable = False + else: +- try: +- socket.gethostbyname("dnspython.org") +- _internet_reachable = True +- except socket.gaierror: +- _internet_reachable = False ++ global _have_ipv4 ++ _have_ipv4 = check_networking(["8.8.8.8", "1.1.1.1"]) ++ global _have_ipv6 ++ _have_ipv6 = check_networking( ++ ["2001:4860:4860::8888", "2606:4700:4700::1111"] ++ ) ++ print(_have_ipv4 or _have_ipv6) ++ _internet_reachable = _have_ipv4 or _have_ipv6 + return _internet_reachable + + ++def have_ipv4(): ++ if not is_internet_reachable(): ++ return False ++ return _have_ipv4 ++ ++ ++def have_ipv6(): ++ if not is_internet_reachable(): ++ return False ++ return _have_ipv6 ++ ++ + def enumerate_module(module, super_class): + """Yield module attributes which are subclasses of given class""" + for attr_name in dir(module): diff -Nru dnspython-2.2.1/debian/patches/0004-tests-Extend-connectivity-check-to-test_async.patch dnspython-2.2.1/debian/patches/0004-tests-Extend-connectivity-check-to-test_async.patch --- dnspython-2.2.1/debian/patches/0004-tests-Extend-connectivity-check-to-test_async.patch 1969-12-31 17:00:00.000000000 -0700 +++ dnspython-2.2.1/debian/patches/0004-tests-Extend-connectivity-check-to-test_async.patch 2022-06-07 13:32:40.000000000 -0600 @@ -0,0 +1,38 @@ +Date: Tue, 7 Jun 2022 13:31:00 -0600 +Description: Extend connectivity check to test_async +Author: Dan Bungert <daniel.bung...@canonical.com> +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/dnspython/+bug/1976565 +Forwarded: https://github.com/rthalley/dnspython/pull/815#discussion_r891618064 +Last-Update: 2022-06-07 +--- + tests/test_async.py | 16 +++++----------- + 1 file changed, 5 insertions(+), 11 deletions(-) + +diff --git a/tests/test_async.py b/tests/test_async.py +index 17c44b4..7bda0b7 100644 +--- a/tests/test_async.py ++++ b/tests/test_async.py +@@ -53,18 +53,12 @@ try: + except Exception: + pass + +-# Probe for IPv4 and IPv6 ++ + query_addresses = [] +-for (af, address) in ((socket.AF_INET, '8.8.8.8'), +- (socket.AF_INET6, '2001:4860:4860::8888')): +- try: +- with socket.socket(af, socket.SOCK_DGRAM) as s: +- # Connecting a UDP socket is supposed to return ENETUNREACH if +- # no route to the network is present. +- s.connect((address, 53)) +- query_addresses.append(address) +- except Exception: +- pass ++if tests.util.have_ipv4(): ++ query_addresses.append("8.8.8.8") ++if tests.util.have_ipv6(): ++ query_addresses.append("2001:4860:4860::8888") + + KNOWN_ANYCAST_DOH_RESOLVER_URLS = ['https://cloudflare-dns.com/dns-query', + 'https://dns.google/dns-query', diff -Nru dnspython-2.2.1/debian/patches/series dnspython-2.2.1/debian/patches/series --- dnspython-2.2.1/debian/patches/series 2022-05-16 12:50:39.000000000 -0600 +++ dnspython-2.2.1/debian/patches/series 2022-06-07 13:32:05.000000000 -0600 @@ -1,2 +1,4 @@ no-setup-requires.patch Allow-skipping-test-cases-that-need-Internet-access.patch +0003-Improve-network-checking-812.patch +0004-tests-Extend-connectivity-check-to-test_async.patch