gh-80931: Skip some socket tests while hunting for refleaks on macOS (#114057)
Some socket tests related to sending file descriptors cause a file descriptor leak on macOS, all of them tests that send one or more descriptors than cannot be received on the read end. This appears to be a platform bug. This PR skips those tests when doing a refleak test run to avoid hiding other problems.
This commit is contained in:
parent
47133d8d86
commit
5adff3f86f
@ -5,6 +5,7 @@ from typing import Any
|
|||||||
|
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
|
from test.support import refleak_helper
|
||||||
|
|
||||||
from .runtests import HuntRefleak
|
from .runtests import HuntRefleak
|
||||||
from .utils import clear_caches
|
from .utils import clear_caches
|
||||||
@ -96,7 +97,12 @@ def runtest_refleak(test_name, test_func,
|
|||||||
support.gc_collect()
|
support.gc_collect()
|
||||||
|
|
||||||
for i in rep_range:
|
for i in rep_range:
|
||||||
results = test_func()
|
current = refleak_helper._hunting_for_refleaks
|
||||||
|
refleak_helper._hunting_for_refleaks = True
|
||||||
|
try:
|
||||||
|
results = test_func()
|
||||||
|
finally:
|
||||||
|
refleak_helper._hunting_for_refleaks = current
|
||||||
|
|
||||||
dash_R_cleanup(fs, ps, pic, zdc, abcs)
|
dash_R_cleanup(fs, ps, pic, zdc, abcs)
|
||||||
support.gc_collect()
|
support.gc_collect()
|
||||||
|
8
Lib/test/support/refleak_helper.py
Normal file
8
Lib/test/support/refleak_helper.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
"""
|
||||||
|
Utilities for changing test behaviour while hunting
|
||||||
|
for refleaks
|
||||||
|
"""
|
||||||
|
|
||||||
|
_hunting_for_refleaks = False
|
||||||
|
def hunting_for_refleaks():
|
||||||
|
return _hunting_for_refleaks
|
@ -3,6 +3,7 @@ from test import support
|
|||||||
from test.support import os_helper
|
from test.support import os_helper
|
||||||
from test.support import socket_helper
|
from test.support import socket_helper
|
||||||
from test.support import threading_helper
|
from test.support import threading_helper
|
||||||
|
from test.support import refleak_helper
|
||||||
|
|
||||||
import _thread as thread
|
import _thread as thread
|
||||||
import array
|
import array
|
||||||
@ -52,6 +53,35 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
_socket = None
|
_socket = None
|
||||||
|
|
||||||
|
def skipForRefleakHuntinIf(condition, issueref):
|
||||||
|
if not condition:
|
||||||
|
def decorator(f):
|
||||||
|
f.client_skip = lambda f: f
|
||||||
|
return f
|
||||||
|
|
||||||
|
else:
|
||||||
|
def decorator(f):
|
||||||
|
@contextlib.wraps(f)
|
||||||
|
def wrapper(*args, **kwds):
|
||||||
|
if refleak_helper.hunting_for_refleaks():
|
||||||
|
raise unittest.SkipTest(f"ignore while hunting for refleaks, see {issueref}")
|
||||||
|
|
||||||
|
return f(*args, **kwds)
|
||||||
|
|
||||||
|
def client_skip(f):
|
||||||
|
@contextlib.wraps(f)
|
||||||
|
def wrapper(*args, **kwds):
|
||||||
|
if refleak_helper.hunting_for_refleaks():
|
||||||
|
return
|
||||||
|
|
||||||
|
return f(*args, **kwds)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
wrapper.client_skip = client_skip
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
def get_cid():
|
def get_cid():
|
||||||
if fcntl is None:
|
if fcntl is None:
|
||||||
return None
|
return None
|
||||||
@ -3814,6 +3844,7 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
|
|||||||
self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC,
|
self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC,
|
||||||
ignore=ignoreflags)
|
ignore=ignoreflags)
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTruncNoBufSize(self):
|
def testCmsgTruncNoBufSize(self):
|
||||||
# Check that no ancillary data is received when no buffer size
|
# Check that no ancillary data is received when no buffer size
|
||||||
# is specified.
|
# is specified.
|
||||||
@ -3823,26 +3854,32 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
|
|||||||
# received.
|
# received.
|
||||||
ignoreflags=socket.MSG_CTRUNC)
|
ignoreflags=socket.MSG_CTRUNC)
|
||||||
|
|
||||||
|
@testCmsgTruncNoBufSize.client_skip
|
||||||
def _testCmsgTruncNoBufSize(self):
|
def _testCmsgTruncNoBufSize(self):
|
||||||
self.createAndSendFDs(1)
|
self.createAndSendFDs(1)
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTrunc0(self):
|
def testCmsgTrunc0(self):
|
||||||
# Check that no ancillary data is received when buffer size is 0.
|
# Check that no ancillary data is received when buffer size is 0.
|
||||||
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 0),
|
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 0),
|
||||||
ignoreflags=socket.MSG_CTRUNC)
|
ignoreflags=socket.MSG_CTRUNC)
|
||||||
|
|
||||||
|
@testCmsgTrunc0.client_skip
|
||||||
def _testCmsgTrunc0(self):
|
def _testCmsgTrunc0(self):
|
||||||
self.createAndSendFDs(1)
|
self.createAndSendFDs(1)
|
||||||
|
|
||||||
# Check that no ancillary data is returned for various non-zero
|
# Check that no ancillary data is returned for various non-zero
|
||||||
# (but still too small) buffer sizes.
|
# (but still too small) buffer sizes.
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTrunc1(self):
|
def testCmsgTrunc1(self):
|
||||||
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 1))
|
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 1))
|
||||||
|
|
||||||
|
@testCmsgTrunc1.client_skip
|
||||||
def _testCmsgTrunc1(self):
|
def _testCmsgTrunc1(self):
|
||||||
self.createAndSendFDs(1)
|
self.createAndSendFDs(1)
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTrunc2Int(self):
|
def testCmsgTrunc2Int(self):
|
||||||
# The cmsghdr structure has at least three members, two of
|
# The cmsghdr structure has at least three members, two of
|
||||||
# which are ints, so we still shouldn't see any ancillary
|
# which are ints, so we still shouldn't see any ancillary
|
||||||
@ -3850,13 +3887,16 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
|
|||||||
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG),
|
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG),
|
||||||
SIZEOF_INT * 2))
|
SIZEOF_INT * 2))
|
||||||
|
|
||||||
|
@testCmsgTrunc2Int.client_skip
|
||||||
def _testCmsgTrunc2Int(self):
|
def _testCmsgTrunc2Int(self):
|
||||||
self.createAndSendFDs(1)
|
self.createAndSendFDs(1)
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTruncLen0Minus1(self):
|
def testCmsgTruncLen0Minus1(self):
|
||||||
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG),
|
self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG),
|
||||||
socket.CMSG_LEN(0) - 1))
|
socket.CMSG_LEN(0) - 1))
|
||||||
|
|
||||||
|
@testCmsgTruncLen0Minus1.client_skip
|
||||||
def _testCmsgTruncLen0Minus1(self):
|
def _testCmsgTruncLen0Minus1(self):
|
||||||
self.createAndSendFDs(1)
|
self.createAndSendFDs(1)
|
||||||
|
|
||||||
@ -3887,29 +3927,38 @@ class SCMRightsTest(SendrecvmsgServerTimeoutBase):
|
|||||||
len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
|
len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
|
||||||
self.checkFDs(fds)
|
self.checkFDs(fds)
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTruncLen0(self):
|
def testCmsgTruncLen0(self):
|
||||||
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0), maxdata=0)
|
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0), maxdata=0)
|
||||||
|
|
||||||
|
@testCmsgTruncLen0.client_skip
|
||||||
def _testCmsgTruncLen0(self):
|
def _testCmsgTruncLen0(self):
|
||||||
self.createAndSendFDs(1)
|
self.createAndSendFDs(1)
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTruncLen0Plus1(self):
|
def testCmsgTruncLen0Plus1(self):
|
||||||
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0) + 1, maxdata=1)
|
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0) + 1, maxdata=1)
|
||||||
|
|
||||||
|
@testCmsgTruncLen0Plus1.client_skip
|
||||||
def _testCmsgTruncLen0Plus1(self):
|
def _testCmsgTruncLen0Plus1(self):
|
||||||
self.createAndSendFDs(2)
|
self.createAndSendFDs(2)
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTruncLen1(self):
|
def testCmsgTruncLen1(self):
|
||||||
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(SIZEOF_INT),
|
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(SIZEOF_INT),
|
||||||
maxdata=SIZEOF_INT)
|
maxdata=SIZEOF_INT)
|
||||||
|
|
||||||
|
@testCmsgTruncLen1.client_skip
|
||||||
def _testCmsgTruncLen1(self):
|
def _testCmsgTruncLen1(self):
|
||||||
self.createAndSendFDs(2)
|
self.createAndSendFDs(2)
|
||||||
|
|
||||||
|
|
||||||
|
@skipForRefleakHuntinIf(sys.platform == "darwin", "#80931")
|
||||||
def testCmsgTruncLen2Minus1(self):
|
def testCmsgTruncLen2Minus1(self):
|
||||||
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(2 * SIZEOF_INT) - 1,
|
self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(2 * SIZEOF_INT) - 1,
|
||||||
maxdata=(2 * SIZEOF_INT) - 1)
|
maxdata=(2 * SIZEOF_INT) - 1)
|
||||||
|
|
||||||
|
@testCmsgTruncLen2Minus1.client_skip
|
||||||
def _testCmsgTruncLen2Minus1(self):
|
def _testCmsgTruncLen2Minus1(self):
|
||||||
self.createAndSendFDs(2)
|
self.createAndSendFDs(2)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user