Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
39708de
Support helpers for running on non-IPv4 IPv6-only hosts.
gpshead May 17, 2021
aa9e7c5
Fixes eight testsuites to work on IPv6-only hosts.
gpshead May 17, 2021
ee00e8b
Make test_support pass on IPv6 only.
gpshead May 18, 2021
29efd49
Make test_os work on IPv6-only.
gpshead May 18, 2021
d51dc79
fix test_telnetlib IPv6-only, introduce get_family helper.
gpshead May 18, 2021
0c95594
Fix test_urllib2_localnet for IPv6-only.
gpshead May 18, 2021
7938fdc
tcp_socket() to replace socket.socket() in tests.
gpshead May 18, 2021
6436757
make test_ssl pass on IPv6-only.
gpshead May 18, 2021
d752f1a
cleanup a bit.
gpshead May 18, 2021
b726756
Make test_httplib pass IPv6-only.
gpshead May 18, 2021
66054f4
Make test_wsgiref pass on IPv6-only.
gpshead May 18, 2021
f20c40a
fix test_smtplib for IPv6-only.
gpshead May 18, 2021
8859b2a
Fix test_poplib for IPv6-only.
gpshead May 18, 2021
d485dc3
Make test_asyncore IPv6-only friendly.
gpshead May 18, 2021
77ed056
make test_asynchat IPv6-only friendly.
gpshead May 18, 2021
99e0665
Add udp_socket(), use SkipTest.
gpshead May 18, 2021
03aac81
Allow test_socket to work on IPv6-only hosts.
gpshead May 18, 2021
56d179e
cleanup test names to clarify IPv4 status.
gpshead May 18, 2021
7d55a83
Add AF_INET6 support to multiprocessing IPC.
gpshead May 19, 2021
1a72129
Fix test_httpservers for IPv6-only hosts.
gpshead May 19, 2021
bc6d51a
If starting a logging config server on AF_INET fails, try AF_INET6.
gpshead May 19, 2021
1317e7a
Fix test_logging for use on IPv6-only hosts.
gpshead May 19, 2021
6d50fa5
Make test_xmlrpc work on IPv6-only hosts rather than hang.
gpshead May 19, 2021
be88847
Prevent test_asyncio from hanging on an IPv6-only host.
gpshead May 19, 2021
5d0f8d7
Fix test_asyncio.test_streams to work on IPv6-only.
gpshead May 19, 2021
0b556da
Fix socket_helper sock vs tempsock paste error..
gpshead May 19, 2021
b7688e4
socket_helper typo (yes, find_unused_port is too ugly...)
gpshead May 19, 2021
2965d32
Undo find_unused_port complexity, use get_family()
gpshead May 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add AF_INET6 support to multiprocessing IPC.
Also makes the test_multiprocessing suites work on IPv6-only hosts.
  • Loading branch information
gpshead committed May 19, 2021
commit 7d55a83b10fa6825df450fc4a2363a4b51228fd6
14 changes: 12 additions & 2 deletions Lib/multiprocessing/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
default_family = 'AF_UNIX'
families += ['AF_UNIX']

if hasattr(socket, 'AF_INET6') and socket.has_ipv6:
families.append('AF_INET6')

if sys.platform == 'win32':
default_family = 'AF_PIPE'
families += ['AF_PIPE']
Expand All @@ -70,7 +73,7 @@ def arbitrary_address(family):
'''
Return an arbitrary free address for the given family
'''
if family == 'AF_INET':
if family in {'AF_INET', 'AF_INET6'}:
return ('localhost', 0)
elif family == 'AF_UNIX':
# Prefer abstract sockets if possible to avoid problems with the address
Expand Down Expand Up @@ -101,9 +104,16 @@ def address_type(address):
'''
Return the types of the address

This can be 'AF_INET', 'AF_UNIX', or 'AF_PIPE'
This can be 'AF_INET', 'AF_INET6', 'AF_UNIX', or 'AF_PIPE'
'''
if type(address) == tuple:
if '.' in address[0]:
return 'AF_INET'
if ':' in address[0]:
return 'AF_INET6'
addr_info = socket.getaddrinfo(*address[:2])
if addr_info:
return addr_info[0][0].name
return 'AF_INET'
elif type(address) is str and address.startswith('\\\\'):
return 'AF_PIPE'
Expand Down
35 changes: 23 additions & 12 deletions Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ class BaseTestCase(object):

ALLOWED_TYPES = ('processes', 'manager', 'threads')

def get_families(self):
fams = set(self.connection.families)
if not socket_helper.IPV6_ENABLED:
fams -= {'AF_INET6'}
if not socket_helper.IPV4_ENABLED:
fams -= {'AF_INET'}
return fams

def assertTimingAlmostEqual(self, a, b):
if CHECK_TIMINGS:
self.assertAlmostEqual(a, b, 1)
Expand Down Expand Up @@ -3284,7 +3292,7 @@ class _TestListener(BaseTestCase):
ALLOWED_TYPES = ('processes',)

def test_multiple_bind(self):
for family in self.connection.families:
for family in self.get_families():
l = self.connection.Listener(family=family)
self.addCleanup(l.close)
self.assertRaises(OSError, self.connection.Listener,
Expand Down Expand Up @@ -3324,7 +3332,7 @@ def _test(cls, address):
conn.close()

def test_listener_client(self):
for family in self.connection.families:
for family in self.get_families():
l = self.connection.Listener(family=family)
p = self.Process(target=self._test, args=(l.address,))
p.daemon = True
Expand All @@ -3351,7 +3359,7 @@ def test_issue14725(self):
l.close()

def test_issue16955(self):
for fam in self.connection.families:
for fam in self.get_families():
l = self.connection.Listener(family=fam)
c = self.connection.Client(l.address)
a = l.accept()
Expand Down Expand Up @@ -3464,7 +3472,8 @@ def _listener(cls, conn, families):
new_conn.close()
l.close()

l = socket.create_server((socket_helper.HOST, 0))
l = socket.create_server((socket_helper.HOST, 0),
family=socket_helper.get_family())
conn.send(l.getsockname())
new_conn, addr = l.accept()
conn.send(new_conn)
Expand All @@ -3481,15 +3490,15 @@ def _remote(cls, conn):
client.close()

address, msg = conn.recv()
client = socket.socket()
client = socket_helper.tcp_socket()
client.connect(address)
client.sendall(msg.upper())
client.close()

conn.close()

def test_pickling(self):
families = self.connection.families
families = self.get_families()

lconn, lconn0 = self.Pipe()
lp = self.Process(target=self._listener, args=(lconn0, families))
Expand Down Expand Up @@ -4638,7 +4647,7 @@ def test_wait(self, slow=False):

@classmethod
def _child_test_wait_socket(cls, address, slow):
s = socket.socket()
s = socket_helper.tcp_socket()
s.connect(address)
for i in range(10):
if slow:
Expand All @@ -4648,7 +4657,8 @@ def _child_test_wait_socket(cls, address, slow):

def test_wait_socket(self, slow=False):
from multiprocessing.connection import wait
l = socket.create_server((socket_helper.HOST, 0))
l = socket.create_server((socket_helper.HOST, 0),
family=socket_helper.get_family())
addr = l.getsockname()
readers = []
procs = []
Expand Down Expand Up @@ -4836,7 +4846,8 @@ def test_timeout(self):
try:
socket.setdefaulttimeout(0.1)
parent, child = multiprocessing.Pipe(duplex=True)
l = multiprocessing.connection.Listener(family='AF_INET')
l = multiprocessing.connection.Listener(
family=socket_helper.get_family().name)
p = multiprocessing.Process(target=self._test_timeout,
args=(child, l.address))
p.start()
Expand Down Expand Up @@ -4910,11 +4921,11 @@ def get_high_socket_fd(self):
# The child process will not have any socket handles, so
# calling socket.fromfd() should produce WSAENOTSOCK even
# if there is a handle of the same number.
return socket.socket().detach()
return socket_helper.tcp_socket().detach()
else:
# We want to produce a socket with an fd high enough that a
# freshly created child process will not have any fds as high.
fd = socket.socket().detach()
fd = socket_helper.tcp_socket().detach()
to_close = []
while fd < 50:
to_close.append(fd)
Expand All @@ -4925,7 +4936,7 @@ def get_high_socket_fd(self):

def close(self, fd):
if WIN32:
socket.socket(socket.AF_INET, socket.SOCK_STREAM, fileno=fd).close()
socket.socket(socket_helper.get_family(), socket.SOCK_STREAM, fileno=fd).close()
else:
os.close(fd)

Expand Down