Skip to content

Commit ec2fafd

Browse files
authored
Enable IPv6 in the CI (#393)
1 parent d67d5f4 commit ec2fafd

2 files changed

Lines changed: 32 additions & 9 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,5 @@ jobs:
2727
pip install .
2828
- name: Run tests
2929
run: make ci
30-
env:
31-
SKIP_IPV6: 1
3230
- name: Report coverage to Codecov
3331
uses: codecov/codecov-action@v1

zeroconf/test.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
import time
1717
import unittest
1818
import unittest.mock
19+
from functools import lru_cache
1920
from threading import Event
2021
from typing import Dict, Optional, cast # noqa # used in type hints
2122

23+
import ifaddr
24+
2225
import pytest
2326

2427
import zeroconf as r
@@ -57,6 +60,28 @@ def teardown_module():
5760
log.setLevel(original_logging_level)
5861

5962

63+
@lru_cache(maxsize=None)
64+
def has_working_ipv6():
65+
"""Return True if if the system can bind an IPv6 address."""
66+
if not socket.has_ipv6:
67+
return False
68+
69+
try:
70+
sock = socket.socket(socket.AF_INET6)
71+
sock.bind(('::1', 0))
72+
except Exception:
73+
return False
74+
finally:
75+
if sock:
76+
sock.close()
77+
78+
for iface in ifaddr.get_adapters():
79+
for addr in iface.ips:
80+
if addr.is_IPv6 and iface.index is not None:
81+
return True
82+
return False
83+
84+
6085
class TestDunder(unittest.TestCase):
6186
def test_dns_text_repr(self):
6287
# There was an issue on Python 3 that prevented DNSText's repr
@@ -550,15 +575,15 @@ def test_close_multiple_times(self):
550575
rv.close()
551576
rv.close()
552577

553-
@unittest.skipIf(not socket.has_ipv6, 'Requires IPv6')
578+
@unittest.skipIf(not has_working_ipv6(), 'Requires IPv6')
554579
@unittest.skipIf(os.environ.get('SKIP_IPV6'), 'IPv6 tests disabled')
555580
def test_launch_and_close_v4_v6(self):
556581
rv = r.Zeroconf(interfaces=r.InterfaceChoice.All, ip_version=r.IPVersion.All)
557582
rv.close()
558583
rv = r.Zeroconf(interfaces=r.InterfaceChoice.Default, ip_version=r.IPVersion.All)
559584
rv.close()
560585

561-
@unittest.skipIf(not socket.has_ipv6, 'Requires IPv6')
586+
@unittest.skipIf(not has_working_ipv6(), 'Requires IPv6')
562587
@unittest.skipIf(os.environ.get('SKIP_IPV6'), 'IPv6 tests disabled')
563588
def test_launch_and_close_v6_only(self):
564589
rv = r.Zeroconf(interfaces=r.InterfaceChoice.All, ip_version=r.IPVersion.V6Only)
@@ -1092,7 +1117,7 @@ def test_integration_with_listener(self):
10921117
finally:
10931118
zeroconf_registrar.close()
10941119

1095-
@unittest.skipIf(not socket.has_ipv6, 'Requires IPv6')
1120+
@unittest.skipIf(not has_working_ipv6(), 'Requires IPv6')
10961121
@unittest.skipIf(os.environ.get('SKIP_IPV6'), 'IPv6 tests disabled')
10971122
def test_integration_with_listener_v6_records(self):
10981123

@@ -1124,7 +1149,7 @@ def test_integration_with_listener_v6_records(self):
11241149
finally:
11251150
zeroconf_registrar.close()
11261151

1127-
@unittest.skipIf(not socket.has_ipv6, 'Requires IPv6')
1152+
@unittest.skipIf(not has_working_ipv6(), 'Requires IPv6')
11281153
@unittest.skipIf(os.environ.get('SKIP_IPV6'), 'IPv6 tests disabled')
11291154
def test_integration_with_listener_ipv6(self):
11301155

@@ -1240,7 +1265,7 @@ def update_service(self, zeroconf, type, name):
12401265
desc = {'path': '/~paulsm/'} # type: Dict
12411266
desc.update(properties)
12421267
addresses = [socket.inet_aton("10.0.1.2")]
1243-
if socket.has_ipv6 and not os.environ.get('SKIP_IPV6'):
1268+
if has_working_ipv6() and not os.environ.get('SKIP_IPV6'):
12441269
addresses.append(socket.inet_pton(socket.AF_INET6, "2001:db8::1"))
12451270
info_service = ServiceInfo(
12461271
subtype, registration_name, port=80, properties=desc, server="ash-2.local.", addresses=addresses
@@ -1344,7 +1369,7 @@ def update_service(self, zeroconf, type, name):
13441369

13451370
class TestServiceBrowser(unittest.TestCase):
13461371
def test_update_record(self):
1347-
enable_ipv6 = socket.has_ipv6 and not os.environ.get('SKIP_IPV6')
1372+
enable_ipv6 = has_working_ipv6() and not os.environ.get('SKIP_IPV6')
13481373

13491374
service_name = 'name._type._tcp.local.'
13501375
service_type = '_type._tcp.local.'
@@ -2110,7 +2135,7 @@ def test_multiple_addresses():
21102135
)
21112136
assert info.addresses == [address, address]
21122137

2113-
if socket.has_ipv6 and not os.environ.get('SKIP_IPV6'):
2138+
if has_working_ipv6() and not os.environ.get('SKIP_IPV6'):
21142139
address_v6_parsed = "2001:db8::1"
21152140
address_v6 = socket.inet_pton(socket.AF_INET6, address_v6_parsed)
21162141
infos = [

0 commit comments

Comments
 (0)