gh-93852: Add test.support.create_unix_domain_name() (#93914)

test_asyncio, test_logging, test_socket and test_socketserver now
create AF_UNIX domains in the current directory to no longer fail
with OSError("AF_UNIX path too long") if the temporary directory (the
TMPDIR environment variable) is too long.

Modify the following tests to use create_unix_domain_name():

* test_asyncio
* test_logging
* test_socket
* test_socketserver

test_asyncio.utils: remove unused time import.
This commit is contained in:
Victor Stinner 2022-06-17 13:16:51 +02:00 committed by GitHub
parent ffc228dd4e
commit c5b750dc0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 86 deletions

View file

@ -1,8 +1,10 @@
import contextlib
import errno
import os.path
import socket
import unittest
import sys
import tempfile
import unittest
from .. import support
from . import warnings_helper
@ -270,3 +272,14 @@ def transient_internet(resource_name, *, timeout=_NOT_SET, errnos=()):
# __cause__ or __context__?
finally:
socket.setdefaulttimeout(old_timeout)
def create_unix_domain_name():
"""
Create a UNIX domain name: socket.bind() argument of a AF_UNIX socket.
Return a path relative to the current directory to get a short path
(around 27 ASCII characters).
"""
return tempfile.mktemp(prefix="test_python_", suffix='.sock',
dir=os.path.curdir)

View file

@ -315,8 +315,12 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase):
self.loop.run_until_complete(coro)
def test_create_unix_server_existing_path_nonsock(self):
with tempfile.NamedTemporaryFile() as file:
coro = self.loop.create_unix_server(lambda: None, file.name)
path = test_utils.gen_unix_socket_path()
self.addCleanup(os_helper.unlink, path)
# create the file
open(path, "wb").close()
coro = self.loop.create_unix_server(lambda: None, path)
with self.assertRaisesRegex(OSError,
'Address.*is already in use'):
self.loop.run_until_complete(coro)
@ -356,11 +360,11 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase):
'no socket.SOCK_NONBLOCK (linux only)')
@socket_helper.skip_unless_bind_unix_socket
def test_create_unix_server_path_stream_bittype(self):
sock = socket.socket(
socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
with tempfile.NamedTemporaryFile() as file:
fn = file.name
try:
fn = test_utils.gen_unix_socket_path()
self.addCleanup(os_helper.unlink, fn)
sock = socket.socket(socket.AF_UNIX,
socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
with sock:
sock.bind(fn)
coro = self.loop.create_unix_server(lambda: None, path=None,
@ -368,8 +372,6 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase):
srv = self.loop.run_until_complete(coro)
srv.close()
self.loop.run_until_complete(srv.wait_closed())
finally:
os.unlink(fn)
def test_create_unix_server_ssl_timeout_with_plain_sock(self):
coro = self.loop.create_unix_server(lambda: None, path='spam',

View file

@ -11,9 +11,7 @@ import selectors
import socket
import socketserver
import sys
import tempfile
import threading
import time
import unittest
import weakref
@ -34,6 +32,7 @@ from asyncio import futures
from asyncio import tasks
from asyncio.log import logger
from test import support
from test.support import socket_helper
from test.support import threading_helper
@ -251,8 +250,7 @@ if hasattr(socket, 'AF_UNIX'):
def gen_unix_socket_path():
with tempfile.NamedTemporaryFile() as file:
return file.name
return socket_helper.create_unix_domain_name()
@contextlib.contextmanager

View file

@ -1828,12 +1828,6 @@ class SocketHandlerTest(BaseTest):
time.sleep(self.sock_hdlr.retryTime - now + 0.001)
self.root_logger.error('Nor this')
def _get_temp_domain_socket():
fn = make_temp_file(prefix='test_logging_', suffix='.sock')
# just need a name - file can't be present, or we'll get an
# 'address already in use' error.
os.remove(fn)
return fn
@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required")
class UnixSocketHandlerTest(SocketHandlerTest):
@ -1845,13 +1839,10 @@ class UnixSocketHandlerTest(SocketHandlerTest):
def setUp(self):
# override the definition in the base class
self.address = _get_temp_domain_socket()
self.address = socket_helper.create_unix_domain_name()
self.addCleanup(os_helper.unlink, self.address)
SocketHandlerTest.setUp(self)
def tearDown(self):
SocketHandlerTest.tearDown(self)
os_helper.unlink(self.address)
@support.requires_working_socket()
@threading_helper.requires_working_threading()
class DatagramHandlerTest(BaseTest):
@ -1928,13 +1919,10 @@ class UnixDatagramHandlerTest(DatagramHandlerTest):
def setUp(self):
# override the definition in the base class
self.address = _get_temp_domain_socket()
self.address = socket_helper.create_unix_domain_name()
self.addCleanup(os_helper.unlink, self.address)
DatagramHandlerTest.setUp(self)
def tearDown(self):
DatagramHandlerTest.tearDown(self)
os_helper.unlink(self.address)
@support.requires_working_socket()
@threading_helper.requires_working_threading()
class SysLogHandlerTest(BaseTest):
@ -2022,13 +2010,10 @@ class UnixSysLogHandlerTest(SysLogHandlerTest):
def setUp(self):
# override the definition in the base class
self.address = _get_temp_domain_socket()
self.address = socket_helper.create_unix_domain_name()
self.addCleanup(os_helper.unlink, self.address)
SysLogHandlerTest.setUp(self)
def tearDown(self):
SysLogHandlerTest.tearDown(self)
os_helper.unlink(self.address)
@unittest.skipUnless(socket_helper.IPV6_ENABLED,
'IPv6 support required for this test.')
class IPv6SysLogHandlerTest(SysLogHandlerTest):

View file

@ -4,31 +4,30 @@ from test.support import os_helper
from test.support import socket_helper
from test.support import threading_helper
import _thread as thread
import array
import contextlib
import errno
import io
import itertools
import socket
import math
import os
import pickle
import platform
import queue
import random
import re
import select
import signal
import socket
import string
import struct
import sys
import tempfile
import threading
import time
import traceback
import queue
import sys
import os
import platform
import array
import contextlib
from weakref import proxy
import signal
import math
import pickle
import re
import struct
import random
import shutil
import string
import _thread as thread
import threading
try:
import multiprocessing
except ImportError:
@ -605,17 +604,18 @@ class SocketTestBase(unittest.TestCase):
def setUp(self):
self.serv = self.newSocket()
self.addCleanup(self.close_server)
self.bindServer()
def close_server(self):
self.serv.close()
self.serv = None
def bindServer(self):
"""Bind server socket and set self.serv_addr to its address."""
self.bindSock(self.serv)
self.serv_addr = self.serv.getsockname()
def tearDown(self):
self.serv.close()
self.serv = None
class SocketListeningTestMixin(SocketTestBase):
"""Mixin to listen on the server socket."""
@ -700,15 +700,10 @@ class UnixSocketTestBase(SocketTestBase):
# can't send anything that might be problematic for a privileged
# user running the tests.
def setUp(self):
self.dir_path = tempfile.mkdtemp()
self.addCleanup(os.rmdir, self.dir_path)
super().setUp()
def bindSock(self, sock):
path = tempfile.mktemp(dir=self.dir_path)
socket_helper.bind_unix_socket(sock, path)
path = socket_helper.create_unix_domain_name()
self.addCleanup(os_helper.unlink, path)
socket_helper.bind_unix_socket(sock, path)
class UnixStreamBase(UnixSocketTestBase):
"""Base class for Unix-domain SOCK_STREAM tests."""
@ -1905,12 +1900,13 @@ class GeneralModuleTests(unittest.TestCase):
self._test_socket_fileno(s, socket.AF_INET6, socket.SOCK_STREAM)
if hasattr(socket, "AF_UNIX"):
tmpdir = tempfile.mkdtemp()
self.addCleanup(shutil.rmtree, tmpdir)
unix_name = socket_helper.create_unix_domain_name()
self.addCleanup(os_helper.unlink, unix_name)
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.addCleanup(s.close)
with s:
try:
s.bind(os.path.join(tmpdir, 'socket'))
s.bind(unix_name)
except PermissionError:
pass
else:

View file

@ -8,7 +8,6 @@ import os
import select
import signal
import socket
import tempfile
import threading
import unittest
import socketserver
@ -98,8 +97,7 @@ class SocketServerTest(unittest.TestCase):
else:
# XXX: We need a way to tell AF_UNIX to pick its own name
# like AF_INET provides port==0.
dir = None
fn = tempfile.mktemp(prefix='unix_socket.', dir=dir)
fn = socket_helper.create_unix_domain_name()
self.test_files.append(fn)
return fn

View file

@ -0,0 +1,4 @@
test_asyncio, test_logging, test_socket and test_socketserver now create
AF_UNIX domains in the current directory to no longer fail with
``OSError("AF_UNIX path too long")`` if the temporary directory (the
:envvar:`TMPDIR` environment variable) is too long. Patch by Victor Stinner.