Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 14 additions & 1 deletion Lib/test/support/socket_helper.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -270,3 +272,14 @@ def filter_error(err):
# __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)
40 changes: 21 additions & 19 deletions Lib/test/test_asyncio/test_unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,15 @@ def test_create_unix_connection_pathlib(self):
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)
with self.assertRaisesRegex(OSError,
'Address.*is already in use'):
self.loop.run_until_complete(coro)
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)

def test_create_unix_server_ssl_bool(self):
coro = self.loop.create_unix_server(lambda: None, path='spam',
Expand Down Expand Up @@ -356,20 +360,18 @@ def test_create_unix_server_path_dgram(self):
'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:
with sock:
sock.bind(fn)
coro = self.loop.create_unix_server(lambda: None, path=None,
sock=sock)
srv = self.loop.run_until_complete(coro)
srv.close()
self.loop.run_until_complete(srv.wait_closed())
finally:
os.unlink(fn)
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,
sock=sock)
srv = self.loop.run_until_complete(coro)
srv.close()
self.loop.run_until_complete(srv.wait_closed())

def test_create_unix_server_ssl_timeout_with_plain_sock(self):
coro = self.loop.create_unix_server(lambda: None, path='spam',
Expand Down
6 changes: 2 additions & 4 deletions Lib/test/test_asyncio/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import socket
import socketserver
import sys
import tempfile
import threading
import time
import unittest
import weakref

Expand All @@ -34,6 +32,7 @@
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


Expand Down Expand Up @@ -251,8 +250,7 @@ class UnixSSLWSGIServer(SSLWSGIServerMixin, SilentUnixWSGIServer):


def gen_unix_socket_path():
with tempfile.NamedTemporaryFile() as file:
return file.name
return socket_helper.create_unix_domain_name()


@contextlib.contextmanager
Expand Down
27 changes: 6 additions & 21 deletions Lib/test/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -1828,12 +1828,6 @@ def test_noserver(self):
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):
Expand All @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
72 changes: 34 additions & 38 deletions Lib/test/test_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,30 @@
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 select
import tempfile
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 os
import pickle
import re
import struct
import platform
import queue
import random
import shutil
import re
import select
import signal
import socket
import string
import _thread as thread
import struct
import sys
import tempfile
import threading
import time
import traceback
from weakref import proxy
try:
import multiprocessing
except ImportError:
Expand Down Expand Up @@ -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."""
Expand Down Expand Up @@ -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."""
Expand Down Expand Up @@ -1905,17 +1900,18 @@ def test_socket_fileno(self):
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)
try:
s.bind(os.path.join(tmpdir, 'socket'))
except PermissionError:
pass
else:
self._test_socket_fileno(s, socket.AF_UNIX,
socket.SOCK_STREAM)
with s:
try:
s.bind(unix_name)
except PermissionError:
pass
else:
self._test_socket_fileno(s, socket.AF_UNIX,
socket.SOCK_STREAM)

def test_socket_fileno_rejects_float(self):
with self.assertRaises(TypeError):
Expand Down
4 changes: 1 addition & 3 deletions Lib/test/test_socketserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import select
import signal
import socket
import tempfile
import threading
import unittest
import socketserver
Expand Down Expand Up @@ -98,8 +97,7 @@ def pickaddr(self, proto):
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

Expand Down
Original file line number Diff line number Diff line change
@@ -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.